CS 520 Web Programming ObjectRelational Mapping with Hibernate
CS 520 Web Programming Object-Relational Mapping with Hibernate and JPA Chengyu Sun California State University, Los Angeles
The Object-Oriented Paradigm The world consists of objects So we use object-oriented languages to write applications We want to store some of the application objects (a. k. a. persistent objects) So we use a Object Database?
The Reality of DBMS Relational DBMS are still predominant n n n Best performance Most reliable Widest support Bridge between OO applications and relational databases n n CLI and embedded SQL Object-Relational Mapping (ORM) tools
Call-Level Interface (CLI) Application interacts with database through functions calls String sql = "select name from items where id = 1"; Connection c = Driver. Manager. get. Connection( url ); Statement stmt = c. create. Statement(); Result. Set rs = stmt. execute. Query( sql ); if( rs. next() ) System. out. println( rs. get. String(“name”) );
Embedded SQL statements are embedded in host language String name; #sql {select name into : name from items where id = 1}; System. out. println( name );
Employee – Application Object public class Employee { Integer id; String name; Employee supervisor; }
Employee – Database Table create table employees ( id name supervisor ); integer primary key, varchar(255), integer references employees(id)
From Database to Application So how do we construct an Employee object based on the data from the database? public class Employee { Integer String Employee } id; name; supervisor; public Employee( Integer id ) { // access database to get name and supervisor …… }
Problems with CLI and Embedded SQL … SQL statements are hard-coded in applications public Employee( Integer id ) { … Prepared. Statment p; p = connection. prepare. Statment( “select * from employees where id = ? ” ); … }
… Problems with CLI and Embedded SQL … Tedious translation between application objects and database tables public Employee( Integer id ) { … Result. Set rs = p. execute. Query(); if( rs. next() ) { name = rs. get. String(“name”); … } }
… Problems with CLI and Embedded SQL Application design has to work around the limitations of relational DBMS public Employee( Integer id ) { … Result. Set rs = p. execute. Query(); if( rs. next() ) { … supervisor = ? ? } }
The ORM Approach employee Application customer account ORM tool Persistent Data Store Oracle, My. SQL, SQL Server … Flat files, XML …
Advantages of ORM Make RDBMS look like ODBMS Data are accessed as objects, not rows and columns Simplify many common operations. E. g. System. out. println(e. supervisor. name) Improve portability n n Use an object-oriented query language (OQL) Separate DB specific SQL statements from application code Caching
Hibernate and JPA Java Persistence API (JPA) n n n Annotations for object-relational mapping Data access API An object-oriented query language JPQL Hibernate n n The most popular Java ORM library An implementation of JPA
Hibernate Usage Hibernate without JPA n n API: Session. Factory, Session, Query, Transaction More features Hibernate with JPA n n n API: Entity. Manager. Factory, Entity. Manager, Query, Transaction Better portability Behaviors are better defined and documented
A Hibernate Example Java classes n Employee. java JPA configuration file n persistence. xml Code to access the persistent objects n Employee. Test. java (Optional) Logging configuration files n log 4 j. properties
Java Classes Plain Java classes (POJOs); however, it is recommended that n n n Each persistent class has an identity field Each persistent class implements the Serializable interface Each persistent field has a pair of getter and setter, which don’t have to be public
O/R Mapping Annotations Describe how Java classes are mapped to relational tables @Entity Persistent Java Class @Id Id field @Basic (can be omitted) Fields of simple types @Many. To. One @One. To. Many @Many. To. Many @One. To. One Fields of class types
persistence. xml <persistence-unit> n name <properties> n n Database information Provider-specific properties No need to specify persistent classes
Access Persistent Objects Entity. Manager. Factory Entity. Manager Query and Typed. Query Transaction n A transaction is required for updates
Some Entity. Manager Methods find( entity. Class, primary. Key ) create. Query( query, result. Class ) persist( entity ) merge( entity ) get. Transaction() http: //sun. calstatela. edu/~cysun/documentation/jpa-2. 0 -api/javax/persistence/Entity. Manager. html
Persist() vs. Merge() Scenario Persist Merge Object passed was never persisted 1. Object added to persistence context as new entity 2. New entity inserted into database at flush/commit 1. State copied to new entity. 2. New entity added to persistence context 3. New entity inserted into database at flush/commit 4. New entity returned Object was previously persisted, but not loaded in this persistence context 1. Entity. Exists. Exception thrown (or a Persistence. Exception at flush/commit) 1. Existing entity loaded. 2. State copied from object to loaded entity 3. Loaded entity updated in database at flush/commit 4. Loaded entity returned Object was previously persisted and already loaded in this persistence context 1. Entity. Exists. Exception thrown (or a Persistence. Exception at flush or commit time) 1. State from object copied to loaded entity 2. Loaded entity updated in database at flush/commit 3. Loaded entity returned http: //blog. xebia. com/2009/03/jpa-implementation-patterns-saving-detached-entities/
Java Persistence Query Language (JPQL) A query language that looks like SQL, but for accessing objects Automatically translated to DB-specific SQL statements select e from Employee e where e. id = : id n From all the Employee objects, find the one whose id matches the given value See Chapter 4 of Java Persistence API, Version 2. 0
Hibernate Query Language (HQL) A superset of JPQL http: //docs. jboss. org/hibernate/core/3. 6 /reference/en-US/html/queryhql. html CSNS Examples n n Course. Dao. Impl Quarter. Dao. Impl
Join in HQL … class User { } Integer id; String username; … class Section { } users id 1 2 username cysun vcrespi Integer id; User instructor; … sections id 1 2 3 instructor_id 1 1 2
… Join in HQL … Query: find all the sections taught by the user “cysun”. n n SQL? ? HQL? ?
… Join in HQL … class User { } Integer id; String username; … Database tables? ? class Section { } Integer id; Set<User> instructors; …
… Join in HQL Query: find all the sections for which “cysun” is one of the instructors n n SQL? ? HQL? ?
hbm 2 ddl Part of the Hibernate Tools package Generate DDL from Java classes and annotations In CSNS 2 and Hibernate Examples, run mvn process-classes
Basic Object-Relational Mapping Class-level annotations n @Entity and @Table Id field n @Id and @Generated. Value Fields of simple types n @Basic (can be omitted) and @Column Fields of class types n @Many. To. One and @One. To. One
Advanced ORM Embedded class Collections Inheritance
Embedded Class public class Address { String street; String city; String state; String zip; } public class User { Integer id; String username String password; Address address; } users id … street city state zip …
Mapping Embedded Class @Embeddable public class Address { String street; String city; String state; String zip; } @Entity public class User { @Id Integer id; String username String password; @Embedded Address address; }
Collection of Simple Types public class Customer { Integer id; String name; String address; Set<String> phones; }
Mapping Element Collection @Element. Collection Set<String> phones; customers Customer_phones id Customer_id phones
Customize Collection Table @Element. Collection @Collection. Table( name = “customer_phones”, join. Columns=@Join. Column(name = “customer_id”) ) @Column(name=“phone”) Set<String> phones;
List of Simple Types Order by property n n @Order. By(“<property_name> ASC|DESC”) Simple types do not have properties @Element. Collection @Order. By(“asc”) List<String> phones; Order by a separate column @Element. Collection @Order. Column(name = “phone_order”) List<String> phones;
Issues Related to Collections of Object Types Relationships (a. k. a. associations) n n one-to-many-to-many Unidirectional vs. Bidirectional Set and List Cascading behaviors
Types of Relationships Many-to-Many-to-One / One-to-Many One-to-One
Many-to-Many Relationship Each entity in E 1 can be related to many entities in E 2 Each entity in E 2 can be related to many entities in E 1 E 2
Many-to-One Relationship Each entity in E 1 can be related to one entities in E 2 Each entity in E 2 can be related to many entities in E 1 E 2
One-to-One Relationship Each entity in E 1 can be related to one entities in E 2 Each entity in E 2 can be related to one entities in E 1 E 2
Relationship Type Examples Books and authors? ? Books and editors? ?
One-To-Many Example A customer may own multiple accounts An account only has one owner
Bidirectional Association – OO Design #1 public class Account { public class Customer { Integer id; Double balance; Date created. On; String name; String address; Set<String> phones; Customer owner; } Set<Account> accounts; }
Unidirectional Association – OO Design #2 public class Account { public class Customer { Integer id; Double balance; Date created. On; String name; String address; Set<String> phones; } Set<Account> accounts; }
Unidirectional Association – OO Design #3 public class Account { Integer id; Double balance; Date created. On; String name; String address; Set<String> phones; Customer owner; } public class Customer { }
Unidirectional vs. Bidirectional Do the three OO designs result in different database schemas? ? Does it make any difference on the application side? ? Which one should we use? ?
Mapping Bidirectional One-To. Many public class Account { public class Customer { Integer id; Double balance; Date created. On; String name; String address; Set<String> phones; @Many. To. One Customer owner; } @One. To. Many(mapped. By=“owner”) Set<Account> accounts; } property
Using List public class Customer { Integer id; String name; String address; Set<String> phones; @One. To. Many(mapped. By=“owner”) @Order. By( “created. On asc” ) List<Account> accounts; }
Many-To-Many Example A customer may own multiple accounts An account may have multiple owners
Mapping Many-To-Many public class Account { public class Customer { Integer id; Double balance; Date created. On; String name; String address; Set<String> phones; @Many. To. Many Set<Customer> owners; } @Many. To. Many(mapped. By=“owners”) Set<Account> accounts; }
Customize Join Table @Many. To. Many @Join. Table( name = “account_owners”, join. Columns=@Join. Column(name = “account_id”), inverse. Join. Columns=@Join. Column(name=“owner_id”) ) Set<Customer> owners;
Cascading Behavior Whether an operation on the parent object (e. g. Customer) should be applied to the children objects in a collection (e. g. List<Account>) Customer c = new Customer(“cysun”); Account a 1 = new Account(); Account a 2 = new Account(); c. get. Accounts(). add( a 1 ); c. get. Accounts(). add( a 2 ); entity. Manager. persist(c); // will a 1 and a 2 be saved as well? entity. Manager. remove(c); // will a 1 and a 2 be deleted from db? ?
Cascading Types in JPA http: //sun. calstatela. edu/~cysun/docum entation/jpa-2. 0 api/javax/persistence/Cascade. Type. html
Cascade. Type Examples @One. To. Many(mapped. By=“owner”, cascade=Cascade. Type. PERSIST) List<Account> accounts; @One. To. Many(mapped. By=“owner”, cascade={Cascade. Type. PERSIST, Cascade. Type. MERGE}) List<Account> accounts; @One. To. Many(mapped. By=“owner”, cascade=Cascade. Type. ALL) List<Account> accounts;
Inheritance public class CDAccount extends Account { Integer term; }
Everything in One Table accounts id account_type balance Discriminator column created_on term
Inheritance Type – SINGLE_TABLE @Entity @Table(name=“accounts”) @Inheritance(strategy=Inheritance. Type. SINGLE_TABLE) @Discriminator. Column(name=“account_type”) @Discrimnator. Value(“CHECKING”) public class Account { … } @Entity @Discrimnator. Value(“CD”) public class CDAccount { … }
Table Per Subclass accounts id balance foreign key cd_accounts account_id term created_on
Inheritance Type – JOINED @Entity @Table(name=“accounts”) @Inheritance(strategy=Inheritance. Type. JOINED) public class Account { … } @Entity @Table(name=“cd_accounts”) public class CDAccount { … }
Table Per Concrete Class accounts id balance created_on cd_accounts id balance created_on term
Inheritance Type – TABLE_PER_CLASS @Entity @Table(name=“accounts”) @Inheritance(strategy=Inheritance. Type. TABLE_PER_CLASS) public class Account { … } @Entity @Table(name=“cd_accounts”) public class CDAccount { … }
Tips for Hibernate Mapping Understand relational design n Know what the database schema should looks like before doing the mapping Understand OO design n Make sure the application design is objectoriented
Further Readings Top. Link JPA Annotation Reference – http: //www. oracle. com/technetwork/mi ddleware/ias/toplink-jpa-annotations 096251. html Pro JPA 2 by Mike Keith and Merrick Schincariol
- Slides: 65