Upload
kenan-sevindik
View
214
Download
1
Embed Size (px)
Citation preview
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● 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@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
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!
Contact
● Harezmi Bilişim Çözümleri A.Ş.● http://www.harezmi.com.tr● [email protected]