45
Hibernate Persistence Framework and Object Relational Mapping

20160523 hibernate persistence_framework_and_orm

Embed Size (px)

Citation preview

Hibernate Persistence Framework and

Object Relational Mapping

Who is Kenan Sevindik?

● Over 15 years of experience in enterprise software development

● Involved in development of architectures of several enterprise projects

● Has extensive knowledge and experience about enterprise Java technologies, such as Spring, Spring Security, Hibernate, Vaadin

Who is Kenan Sevindik?

● Co-author of Beginning Spring Book

● Founded Harezmi IT Solutions in 2011

● What Harezmi offers?– Enterprise software

development services

– Mentoring and consultancy services

– Organizing trainings about enterprise Java technologies

Introduction To ORM

Uygulama

ORM(Hibernate)

DB

ORM solutions help us to handle persistent data on Java side

They lay between service and database layers

Their aim is to let developers focus more on business logic

Persistence operations are performed over domain model as much as possible

Domain Model / Object Model

E-R Model / Data Model

Advantages of ORM

● You model entities (domain objects) based on real business concepts rather than based on your DB structure

● Reduces considerable amount of code to perform repetitive persistence operations (CRUD) over entities

● Provides rich query capabilities based on object oriented concepts rather than relational algebra

● Encapsulates vendor specific SQL

Paradigm Shift

Object Oriented World ≠ Relational World

Paradigm Shift● Granularity problem

– It is not always the case that each table matches with one and only one class or vice versa

● Problem with directional relationships– Domain model contains direction information

between entity relations

– Relational model has no direction information on the other hand

● Identity problem– Database identity, object identity and object equality

are just three differenent concepts and you should be aware of them

Paradigm Shift

● Subclass problem and polymorphic queries– A class hierarchy can be mapped into several

different table combinations

– Any ORM solution should allow developers to query objects over their super classes and interfaces

● Problem with object network traversal– Domain model is suitable to be traversed one by

one as information is needed in application

– Relational model, on the other hand, is more suitable to fetch necessary data once in the beginning

What is JPA? and Relationship between Hibernate & JPA

Service Layer

DAO Layer

JPA

Hibernate

DB

HibernateWorld

JPAWorld

JPA is ORM specification of EJB3

Hibernate on the other hand is one of those JPAimplementations. Others are; EclipseLink, OpenJPA, DataNucleus

Benefits of JPA

● Standardization of discovery of metadata eases configuration steps

● Configuration of ORM part becomes standard in any enterprise Java application

● Persistence operations are performed over a standard data access API

Compartments of an ORM Solution

● Any ORM solution consists of four fundamental parts

– Metadata definition capability– API for CRUD operations– Persistence Context to track changes made

on domain objects, to manage lazy associations

– Query/Criteria API for search requirements

O/R Mapping Metadata

● Metadata means data about data● ORM solution makes use of this metadata to deal

with domain objects and relational data● It helps ORM to transform data/state from one

representation into another

METADATA

O/R Mapping Metadata

● ORM solution maps between following structures– Classes & tables

– Properties & columns

– Associations & foreign keys

– Java types & SQL types

Metadata Example@Entity@Table(name="T_PET")public class Pet {

@Idprivate Long id;

@Column(name="PET_NAME")private String name;

public void setId(Long id) {this.id = id;

}public Long getId() {

return id;}

public void setName(String name) {this.name = name;

}public String getName() {

return name;}

}

Metadata Example (XML)

<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping> <class name="com.javaegitimleri.petclinic.model.Pet" table="PETS"> <id name="id" type="long"> <column name="ID" /> <generator class="assigned" /> </id> <property name="name" type="string"> <column name="NAME" /> </property> </class></hibernate-mapping>

Entity Associations

● Associations between entities can be examined from several different perspectives– According to multiplicity: single sided (M:1,1:1), many

sided (1:M,M:N)

– According to aggregate type used in many sided associations (list, set, map, bag)

– According to direction of the association (unidirectional, bidirectional)

– According to using a separate join table or join column to keep association information

M:1@Entitypublic class Pet {

@ManyToOne@JoinColumn(name = "TYPE_ID")private PetType petType;

}

@Entitypublic class PetType {

}

T_PET_TYPE

ID1

T_PET

ID TYPE_ID

101 1

1:M – Unidirectional Set@Entitypublic class Pet { @OneToMany @JoinColumn(name = "PET_ID") private Set<Visit> visits =

new HashSet <Visit>(); }

@Entitypublic class Visit {

}

T_PET

ID1

T_VISIT

ID PET_ID

55 1

1:M – Unidirectional List@Entitypublic class Owner {

@OneToMany @JoinColumn(name = "OWNER_ID")

@OrderColumn(name = "PET_POSITION")

private List<Pet> pets = new ArrayList<Pet>();

}

@Entitypublic class Pet {

}

ID OWNER_ID PET_POSITION NAME

1 1 0 Foo

2 1 1 Bar

3 2 0 Bat

4 1 2 Baz

PET TABLOSU

1:M – Bidirectional Set

public class Owner { @OneToMany(mappedBy = "owner") private Set<Pet> pets = new HashSet<Pet>(); }

public class Pet {

@ManyToOne @JoinColumn(name = "OWNER_ID")

private Owner owner;

}

1:M & Using Join Table@Entitypublic class Owner {

@OneToMany @JoinTable( name = "T_OWNER_PET", joinColumns = {@JoinColumn(name = "OWNER_ID")}, inverseJoinColumns = {@JoinColumn(name = "PET_ID")})

private Set<Pet> pets = new HashSet<Pet>();}

@Entitypublic class Pet {

}

T_OWNER

ID

T_PET

ID

T_OWNER_PET

OWNER_ID , PET_ID

Unidirectional N:M@Entitypublic class Vet {

@ManyToMany

@JoinTable(name = "T_VET_SPECIALTY", JoinColumns = {@JoinColumn(name="VET_ID")},

inverseJoinColumns = {@JoinColumn(name="SPECIALTY_ID")})

private Set<Specialty> specialties=new HashSet<Specialty>();}

@Entitypublic class Specialty {

}

Inheritance

● Using single table for complete class hierarchy● Using separate tables for each distinct class

(abstract or concrete) in the hierarchy● Using separate tables only for concrete

classes in the hierarchy

Single Table

T_PERSON

IDFIRST_NAMELAST_NAMEEMAILGRADUATION_YEARPERSON_TYPE

Single Table@Entity@Inheritance(strategy = InheritanceType.SINGLE_TABLE)@DiscriminatorColumn(name = "PERSON_TYPE", discriminatorType = DiscriminatorType.STRING)public abstract class Person { @Id @GeneratedValue private Long id = null; //…}

@Entity@DiscriminatorValue("O")public class Owner extends Person { //…}

@Entity@DiscriminatorValue("V")public class Vet extends Person { //…}

Separate Tables for Each Distinct Class

T_OWNER

IDEMAIL

T_PERSON

IDFIRST_NAMELAST_NAME

T_VET

IDGRADUATION_YEAR

Separate Tables for Each Distinct Class

@Entity@Inheritance(strategy = InheritanceType.JOINED)public abstract class Person { @Id @GeneratedValue private Long id = null; //…}

@Entitypublic class Owner extends Person { //…}

@Entity@PrimaryKeyJoinColumn(name = "VET_ID")public class Vet extends Person { //…}

Separate Table Only For Concrete Classes

T_OWNER

IDFIRST_NAMELAST_NAMEEMAIL

T_VET

IDFIRST_NAMELAST_NAMEGRADUATION_YEAR

@MappedSuperclasspublic abstract class Person {

@Id @GeneratedValue @Column(name = "ID") private Long id = null;

//…}

@Entity@AttributeOverride(name = "id", column = @Column(name = "VET_ID"))public class Vet extends Person { //…}

Separate Table Only For Concrete Classes

@Entitypublic class Vet extends Person { //…}

Polymorphic Associations

for( Person person : petClinic.getPersons() ) { //Person spesifik metotlar çağrılabilir... }

T_PETCLINIC

ID

T_OWNER

IDFIRST_NAMELAST_NAMEEMAILCLINIC_ID

T_VET

IDFIRST_NAMELAST_NAMEGRADUATION_YEARCLINIC_ID

FK FK

Polymorphic Associations & Only For Concrete Classes Method

Polymorphic Associations & Only For Concrete Classes Method

T_PETCLINIC

IDOWNER_IDVET_ID

T_OWNER

IDFIRST_NAMELAST_NAMEEMAIL

T_VET

IDFIRST_NAMELAST_NAMEGRADUATION_YEAR

FK FK

Persistent Domain Objects & State Transitions

Session session = null;Transaction transaction = null;try { session = sessionFactory.openSession(); tx = session.beginTransaction();

Pet kedi = new Pet(); kedi.setName("boncuk");

session.save(kedi);

transaction.commit();} catch (RuntimeException ex) { transaction.rollback();} finally { session.close();}

Persistence API Example

Persistence operation must alwaysexecute within an active TX block

Object Query Languages

● Any ORM tool provides a mechanism to perform data fetching via a query mechanism

● That query mechanism is based on object graph and navigation between object relationships

● JPA and Hibernate provide their own object query languages and programmatic query generation mechanisms as well

Sample Object Queries

● from Pet

● from Pet as p

● from Pet p

● from Person

● from Owner

● from java.lang.Object

● from java.io.Serializable nesneleri döner

● from Owner o where o.email = '[email protected]'

Sample Object Queries

● from Owner o where p.email in ('foo@bar', 'bar@foo')

● from Owner o where p.email is null

● from Owner o where p.email is not null

● from Person p where p.firstName like 'G%'

● from Person p where p.firstName not like '%Foo B%'

● from Person p where p.firstName not like '\%Foo%' escape='\'

● from Person p order by p.firstName

● from Person p order by p.firstName desc

● from Person p order by p.lastName asc, p.firstName desc

Sample Object Queries

● from Person p where p.firstName like 'G%' and p.lastName like 'K%'

● from Owner o where (o.firstName like 'G%' and o.lastName like 'K%') or o.email in ('foo@bar', 'bar@foo')

● from Owner o where lower(o.email) = '[email protected]'

● from Person p where concat(p.firstName, p.lastName) like 'G% K%'

● from Pet p where p.visits is not empty

● from Pet p where size(p.visits) > 0

● from Pet p, Owner o where p member of o.pets and p.name like '%Kitty%'

Sample Object Queries

● from Item i where i.price between 1 and 100

● from Item i where i.price > 100

● from Item i where ( i.price / 0.71 ) - 100.0 > 0.0

Executing Queries

Query query = session.createQuery("from Pet p order by p.name desc");

List pets = query.list();

Pet pet = (Pet) session.createQuery("from Pet p where p.id = 1").uniqueResult();

Conclusion

● ORM is not a one size fits all solution● It is very useful for some sort of

applications, but not for others● It helps you to reduce persistence related

code you write● It may simplify queries to fetch data

Conclusion

● “We can forget about/ignore SQL, because we are using Hibernate/JPA” thinking is a big mistake

● It is very easy to create performance bottlenecks in your applications while using ORM

● It has a steep learning curve, so be prepared before you start using it in your next big project!

Choice is Yours!

Questions & Answers

Contact

● Harezmi Bilişim Çözümleri A.Ş.● http://www.harezmi.com.tr● [email protected]