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 ( ’” +
[Link]() + ”’, ’” + [Link]() + ”’ )”;
// 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 ) {
[Link] = 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 ) {
[Link] = 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"
"[Link]
<hibernate-mapping>
Class element <class name=”[Link]” 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=”[Link]”/>
association mapping </set>
</class>
</hibernate-mapping>
Filename: [Link]
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=”[Link]”/>
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
[Link] string VARCHAR
[Link] date, time DATE, TIME
[Link], int integer INT
[Link] class varchar
[Link] 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
○ [Link] = [Link].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.
[Link], the application must obtain
a factory to get [Link]
● SessionFactory provides [Link]
instances to the application
● Shared among application threads
● Most important method is getCurrentSession
SessionFactory sessionFactory = [Link]();
OR let Spring inject it for you
<bean id="sessionFactory" class="[Link]">
<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 = [Link]();
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) [Link]( event );
Load an object – if
Event event = (Event) [Link]( [Link], id );
matching row exists
Load an object – if
Event event = (Event) [Link]( [Link], id );
unsure about matching row
Delete an object – make
[Link]( event );
it transient again
The Session interface
Update an object – if its
[Link]( event );
detached
Update or save an object – if
[Link]( event );
you’re unsure about the state
Synchronize database with
[Link](); // Happens auto. at [Link]()
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 = [Link]( [Link] );
Retrieve all instances of Event
List events = [Link]();
Criteria criteria = [Link]( [Link] );
[Link]( [Link]( ”title”, ”Rolling Stones” ) );;
[Link]( [Link]( ”date”, new Date() ) );
Narrow the result set
[Link]( 10 );
List events = [Link]();
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>[Link]</groupId>
<dependency> <artifactId>hibernate-core</artifactId>
<version>${[Link]}</version>
<groupId>[Link]</groupId> </dependency>
<artifactId>spring-core</artifactId> <dependency>
<version>${[Link]}</version> <groupId>[Link]</groupId>
<artifactId>hibernate-entitymanager</artifactId>
</dependency> <version>3.5.1-Final</version>
<dependency> </dependency>
<groupId>[Link]</groupId> <dependency>
<groupId>geronimo-spec</groupId>
<artifactId>spring-context</artifactId> <artifactId>geronimo-spec-jta</artifactId>
<version>${[Link]}</version> <version>1.0-M1</version>
</dependency> </dependency>
<dependency>
<dependency> <groupId>c3p0</groupId>
<groupId>[Link]</groupId> <artifactId>c3p0</artifactId>
<artifactId>spring-tx</artifactId> <version>[Link]</version>
</dependency>
<version>${[Link]}</version> <dependency>
</dependency> <groupId>org.slf4j</groupId>
<dependency> <artifactId>slf4j-log4j12</artifactId>
<version>1.5.8</version>
<groupId>[Link]</groupId> </dependency>
<artifactId>spring-orm</artifactId> <dependency>
<version>${[Link]}</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="[Link]">
<property name="sessionFactory" ref="sessionFactory"/>
<property name="dataSource" ref="dataSource"/>
</bean>
Can be
injected
<bean id="sessionFactory" class="[Link]"> like any bean
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<value>hibernate/[Link]</value>
<value>hibernate/[Link]</value> Points to
</list>
</property> mapping files
<property name="hibernateProperties">
<props>
<prop key="[Link]">[Link].H2Dialect</prop>
<prop key="[Link]">create-drop</prop> Hibernate properties
</props>
</property> ● H2 database (fast inmemory DB)
</bean> ● Automatically create tables
<bean id="dataSource" class="[Link]" destroy-method="close">
<property name="driverClass" value="[Link]"/>
<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
[Link]
framework-reference/html/[Link]
● Hibernate reference documentation
● [Link] -> Documentation -> Reference