Object Relational
Mapping (ORM)
and Hibernate
INF5750/9750 - Lecture 2 (Part III)
Problem area
● When working with object-oriented systems, there’s a
mismatch between the object model and the relational
database
● How do we map one to the other?
public class Student
{
private String name;
private String address;
private Set<Course> courses;
private Set<Degree> degrees;
}
Java object with properties Relational database
and associations with tables and columns
Problem area
● How to map associations between objects?
○ References are directional, foreign keys not
○ Foreign keys can’t represent many-to-many associations
public class Student
N N {
Student Degree private Collection<Degree> degrees;
Java
...
STUDENT DEGREE
student_id degree_id
name type
Relational
address name database
degree_id
Need for ORM
● Write SQL conversion methods by hand using JDBC
○ Tedious and requires lots of code
○ Extremely error-prone
○ Non-standard SQL ties the application to specific databases
○ Vulnerable to changes in the object model
○ Difficult to represent associations between objects
public void addStudent( Student student )
{ Student Course
String sql = ”INSERT INTO student ( name, address ) VALUES ( ’” +
student.getName() + ”’, ’” + student.getAddress() + ”’ )”;
// Initiate a Connection, create a Statement, and execute the query
} Degree
Approaches to ORM
● Use Java serialization – write application state to a file
○ Can only be accessed as a whole
○ Not possible to access single objects
● Object oriented database systems
○ No complete query language implementation exists
○ Lacks necessary features
The preferred solution
● Use a Object-Relational Mapping System (eg. Hibernate)
● Provides a simple API for storing and retrieving Java
objects directly to and from the database
● Non-intrusive: No need to follow specific rules or design
patterns
● Transparent: Your object model is unaware
Student Course ORM / Hibernate
Magic happens
Degree
here!
(Domain model) (Relational database)
ORM and Architecture
Presentation Layer
● Middleware that
manages persistence
● Provides an abstraction
layer between the Service/Business Layer Domain
domain model and the Model
database
Persistence Layer
ORM / Hibernate
(Database)
Example app: The EventManager
Java Hibernate
objects API
Hibernate Hibernate
mapping files configuration
Java objects (POJO)
public class Event
Identifier property {
(optional) private int id;
private String title;
private Date date;
private Set<Person> persons = new HashSet<Person>();
No-argument constructor
(required) public Event() {
}
public int getId() {
return id;
Declare accessors and mutators for }
persistent fields (optional) private void setId( int id ) {
this.id = id;
● Properties need not be declared }
public - Hibernate can persist a
property with a default, protected or public String getTitle() {
private get / set pair. return title;
}
public void setTitle( String title ) {
this.title = title;
}
Prefer non-final classes
(optional) // Getter and setter for date and persons
}
Example app: The EventManager
Java Hibernate
objects API
Hibernate Hibernate
mapping files configuration
Hibernate mapping files
● Tells Hibernate which tables and columns to use to load
and store objects
<!DOCTYPE hibernate-mapping PUBLIC
DTD "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
Class element <class name=”no.uio.inf5750.Event” table=”events”>
<id name="id” column=”event_id”>
<generator class="native"/>
Identifier mapping & generation </id>
<property name=”title” not-null=”true” unique=”true”/>
Property mapping <property name=”date” type=”date” column=”event_date”/>
<set name=”persons” table=”event_persons”>
<key column=”event_id”/>
Unidirectional many-to-many <many-to-many column=”person_id”
class=”no.uio.inf5750.example.model.Person”/>
association mapping </set>
</class>
</hibernate-mapping>
Filename: Event.hbm.xml
Property mapping
The name property refers Title must be
to the get/set-methods not null and unique
...
<property name=”title” not-null=”true” unique=”true”/>
<property name=”date” type=”Date” column=”event_date”/>
...
Types are Hibernate mapping types. Property name used as
Hibernate will guess if no type is specified. default if no column is specified
Association mapping
The name property refers Many-to-many associations
to the get/set-methods require a link table
Column name ...
for ”this” side <set name=”persons” table=”event_persons”>
of association
<key column=”event_id”/>
<many-to-many column=”person_id”
Column name class=”no.uio.inf5750.example.model.Person”/>
for ”other” side
</set>
of association
...
Reference to the
associated class
Hibernate mapping types
● Hibernate will translate Java types to SQL / database types
for the properties of your mapped classes
Java type Hibernate type SQL type
java.lang.String string VARCHAR
java.util.Date date, time DATE, TIME
java.lang.Integer, int integer INT
java.lang.Class class varchar
java.io.Serializable serializable BLOB, BINARY
Example app: The EventManager
Java Hibernate
objects API
Hibernate Hibernate
mapping files configuration
Hibernate configuration
● Also referred to hibernate properties
● Each database has a dialect
○ hibernate.dialect = org.hibernate.dialect.H2Dialect
● Must also specify:
○ JDBC driver class
○ Connection URL
○ Username
○ Password
● More later in the lecture...
Example app: The EventManager
Java Hibernate
objects API
Hibernate Hibernate
mapping files configuration
The SessionFactory interface
● When all mappings have been parsed by the org.
hibernate.cfg.Configuration, the application must obtain
a factory to get org.hibernate.Session
● SessionFactory provides org.hibernate.Session
instances to the application
● Shared among application threads
● Most important method is getCurrentSession
SessionFactory sessionFactory = cfg.buildSessionFactory();
OR let Spring inject it for you
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
….
</bean
The Session interface
● Obtained from a SessionFactory
● Main runtime interface between a Java application and
Hibernate
● Responsible for storing and retrieving objects
● Think of it as a collection of loaded objects related to a
single unit of work
Session session = sessionFactory.getCurrentSession();
Instance states
● An object instance state is related to the persistence
context
● The persistence context = a Hibernate Session instance
● Three types of instance states:
○ Transient
■ The instance is not associated with any persistence context
○ Persistent
■ The instance is associated with a persistence context
○ Detached
■ The instance was associated with a persistence context which
has been closed – currently not associated
The Session interface
Make a transient object Event event = new Event( ”title”, new Date() );
persistent
Integer id = (Integer) session.save( event );
Load an object – if
Event event = (Event) session.load( Event.class, id );
matching row exists
Load an object – if
Event event = (Event) session.get( Event.class, id );
unsure about matching row
Delete an object – make
session.delete( event );
it transient again
The Session interface
Update an object – if its
session.update( event );
detached
Update or save an object – if
session.saveOrUpdate( event );
you’re unsure about the state
Synchronize database with
session.flush(); // Happens auto. at transaction.commit()
persistence context
The Criteria interface
● You need a query when you don’t know the identifiers of
the objects you are looking for
● Criteria used for programmatic query creation
Criteria criteria = session.createCriteria( Event.class );
Retrieve all instances of Event
List events = criteria.list();
Criteria criteria = session.createCriteria( Event.class );
criteria.add( Restrictions.eq( ”title”, ”Rolling Stones” ) );;
criteria.add( Restrictions.gt( ”date”, new Date() ) );
Narrow the result set
criteria.setMaxResults( 10 );
List events = criteria.list();
Transactions
● Transaction: A set of database operations which must
be executed in entirety or not at all
● Should end either with a commit or a rollback
● All communication with a database has to occur inside a
transaction!
Transaction begins
Operation A: INSERT INTO...
Transaction rollback
Operation B: INSERT INTO... (ERROR)
(SUCCESS)
Transaction commit
Hibernate in real-life apps
● Spring used for SessionFactory management
○ Spring has excellent ORM integration
○ Custom SessionFactory management is “boilerplate-code”
● Spring used for Transaction management
○ Custom tx management is error prone
○ Support for declarative tx management with annotations
○ Consistent programming model across JTA, JDBC, Hibernate
● Annotate transactional methods / class with @Transactional
● Hibernate’s own connection pooling is basic. Hibernate allows
external JDBC pooling through library called C3P0
Spring-Hibernate dependencies
...
<dependency>
... <groupId>org.hibernate</groupId>
<dependency> <artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
<groupId>org.springframework</groupId> </dependency>
<artifactId>spring-core</artifactId> <dependency>
<version>${spring.version}</version> <groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
</dependency> <version>3.5.1-Final</version>
<dependency> </dependency>
<groupId>org.springframework</groupId> <dependency>
<groupId>geronimo-spec</groupId>
<artifactId>spring-context</artifactId> <artifactId>geronimo-spec-jta</artifactId>
<version>${spring.version}</version> <version>1.0-M1</version>
</dependency> </dependency>
<dependency>
<dependency> <groupId>c3p0</groupId>
<groupId>org.springframework</groupId> <artifactId>c3p0</artifactId>
<artifactId>spring-tx</artifactId> <version>0.9.1.2</version>
</dependency>
<version>${spring.version}</version> <dependency>
</dependency> <groupId>org.slf4j</groupId>
<dependency> <artifactId>slf4j-log4j12</artifactId>
<version>1.5.8</version>
<groupId>org.springframework</groupId> </dependency>
<artifactId>spring-orm</artifactId> <dependency>
<version>${spring.version}</version> <groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency> <version>1.2.136</version>
</dependency>
Spring-Hibernate configuration
<tx:annotation-driven transaction-manager="transactionManager"/>
Enables
annotations
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
<property name="dataSource" ref="dataSource"/>
</bean>
Can be
injected
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> like any bean
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<value>hibernate/Event.hbm.xml</value>
<value>hibernate/Person.hbm.xml</value> Points to
</list>
</property> mapping files
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">create-drop</prop> Hibernate properties
</props>
</property> ● H2 database (fast inmemory DB)
</bean> ● Automatically create tables
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="org.h2.Driver"/>
<property name="jdbcUrl" value="jdbc:h2:mem:eventmanager;DB_CLOSE_ON_EXIT=FALSE"/> Connection
<property name="user" value="sa"/> properties
<property name="password" value=""/>
</bean>
Example: The EventManager
Java Hibernate
objects API
Hibernate Hibernate
mapping files configuration
Advantages of ORM
● Productivity
○ Eliminates lots of repetitive code – focus on business logic
○ Database schema is generated automatically
● Maintainability
○ Fewer lines of code – easier to understand
○ Easier to manage change in the object model
● Database vendor independence
○ The underlying database is abstracted away
○ Can be configured outside the application
● Performance
○ Lazy loading – associations are fetched when needed
○ Caching
Resources
● Spring documentation chapter 13
http://static.springsource.org/spring/docs/3.2.x/spring-
framework-reference/html/orm.html
● Hibernate reference documentation
● www.hibernate.org -> Documentation -> Reference