Download as ppt, pdf, or txt
Download as ppt, pdf, or txt
You are on page 1of 54

Object-Relational Mapping with

Hibernate
Brian Sam-Bodden
Principal Partner
Integrallis Software, LLC.

August 1 - 5, 2005
Contents
• The Problem
• Object-Relational Mapping
• Hibernate Core Concepts
• Hibernate Architecture
• Hibernate Mappings
• Configuring Hibernate
• Working with Persistent Objects
• Persistence Lifecycle
Contents
• Working with Collections
• More on Association Mappings
• HQL – The Hibernate Query Language
• Query by Criteria
• Query by Example
• Caching
• Other Hibernate Features
• Conclusions
The Problem
Two Different Worlds
Object-Oriented Systems Relational Databases
• Represent a problem in • Efficient data storage,
terms of objects retrieval and integrity of
• Semantically richer, the data
encapsulate data and • Provide a “normalized”
behavior set of data
The Problem
Natural Divergence
• Early on in a system’s life, both models tend to
look alike
• As the system matures two models diverge
• They grow to do what they do best
– Object model gets richer
– Data model changes to accommodate
operational factors
The Problem
Object-Relational Mismatch
• Granularity
– Object Oriented vs. Database Types
– User-Defined Column Types (UDT) are not
portable
• Inheritance & Polymorphism
– Not supported in the relational model
– No polymorphic queries
– Columns are strictly typed
The Problem
Object-Relational Mismatch
• Identity Mismatch
– Object Identity vs. Object Equality
– Different objects can map to the same column
or columns
– Database Identity Strategies
– Natural Keys versus Surrogate Keys
The Problem
Object-Relational Mismatch
• Associations
– Object References versus Foreign Keys
– Directionality of Associations
– Tables associations are always one-to-many
or many-to-one
– Object associations can be many-to-many
The Problem
Object-Relational Mismatch
• Object Graph Navigation
– Object-oriented applications “walk” the
object graph
– Object-oriented systems access what they
need
– With database we need a “plan” of what to
retrieve
– N+1 Problem is a common symptom
Object-Relational Mapping
• Tools/techniques to store and retrieve objects from a
database
• From the code perspective it behaves like a virtual
object database
• A complete ORM solution should provide:
– Basic CRUD functionality
– An Object-Oriented Query Facility
– Mapping Metadata support
– Transactional Capability
Hibernate
Relational Persistence For Idiomatic Java

• Provides
– Transparent persistence
– Object-querying capabilities
– Caching
• Works with fine-grained POJO-based models
• Supports most Databases
• Created by Gavin King, now part of the JBoss Group
Hibernate
Relational Persistence For Idiomatic Java
• Declarative programming
• Uses Runtime Reflection
• Query Language is SQL-like
– Leverages programmer’s knowledge
• Mappings
– Typically defined as XML documents
• But you never have to write XML if you don’t
want to (XDoclet, JSE 1.5 Annots)
Hibernate
Relational Persistence For Idiomatic Java
Hibernate
Core Concepts
• Session Factory
– is a cache of compiled mappings for a single database.
– used to retrieve Hibernate Sessions
• Session
– Short lived
• Temporary bridge between the app and the data storage
– Provides CRUD operations on Objects
– Wraps a JDBC Connection / J2EE Data Source
– Serves as a first level object cache
Architecture
Architecture
Choices

• How much you use depends on your needs


– Lightweight
• Basic persistence
– Fully Integrated
• Transactions
• Caching
• Connection Pooling
O/R Mappings

• Hibernate Mapping (.hbm.xml) Files define:


– Column to Field Mappings
– Primary Key mapping & generation Scheme
– Associations
– Collections
– Caching Settings
– Custom SQL
– And many more settings…
HBM XML File
<hibernate-mapping
package="com.integrallis.techconf.domain">
<class name="Address">
<id name="Id" column="PK_ID" type="integer">
<generator class="identity" />
</id>
<property name="StreetAddress“ />

<property name="AptNumber" />
</class>
</hibernate-mapping>
O/R Mappings

• Hibernate uses smart defaults


• Mapping files can be generated:
– Manually
• Tedious, boring and error prone
• Total control of the mapping
– From POJOs
• XDoclet, Annotations
– From Database Schema
• Middlegen, Synchronizer, Hibernate Tools
Configuring Hibernate

• Hibernate Session Factory configured via


hibernate.cfg.xml
• CFG file determines which mappings to load
(.hbm.xml files)
• In your application SessionFactory is a singleton
• You request a Session as needed to work with
persistent objects
The Big Picture
Working with Persistent Objects
Saving an Object
Address address = new Address(); • POJO is created
...
• Start a Session
Session session = null;
• Transaction is started
Transaction tx = null;
• The object is saved
try {
• The transaction is
session = factory.openSession();
committed
tx = session.beginTransaction();
• The session is closed
session.save(address);
tx.commit();

} finally {
session.close();
}
Working with Persistent Objects
Loading an Object
Address address = null; • Start a Session
Session session = null; • POJO is loaded
session = factory.openSession(); • PK and Object Class are
try { provided
address = (Address) • The session is closed
session.get(Address.class, id);

} finally {
session.close();
}
Working with Persistent Objects
Deleting an Object
Session session = null; • Start a Session
Transaction tx = null; • Transaction is started
try { • The object is deleted
session = factory.openSession(); • The transaction is
tx = session.beginTransaction(); committed
session.delete(address); • The session is closed
tx.commit();

} finally {
session.close();
}
Persistence Lifecycle
Possible States
• Transient
– Not Associated with a database table
– Non-transactional
• Persisted
– Object with Database Identity
– Associates object with a Session
– Transactional
• Detached
– no longer guaranteed to be in synch with the
database
Persistence Lifecycle
Working with Collections

• Can represent a parent-child/one-many relationship


using most of the available Java Collections
• Persistence by reach-ability
• No added semantics to your collections
• Available Collection mappings are
– <set>, <list>, <map>, <bag>, <array> and <primitive-
array>
• In the database mappings are defined by a foreign
key to the owning/parent entity
Working with Collections
A simple example
Working with Collections
A simple example
public class Conference implements Serializable {
...
// Tracks belonging to this Conference
private Set tracks;
public Set getTracks () { return tracks; }
public void setTracks (Set tracks) { this.tracks = tracks; }

// maintain bi-directional association


public void addTrack(Track track) {
if (null == tracks) tracks = new HashSet();
track.setConference(this);
tracks.add(track);
}
Working with Collections
A simple example
<hibernate-mapping
package="com.integrallis.tcms.domain"> •Class/Table
<class name="Conference"> •How to generate PK
<id column="PK_ID" name="Id“ •Other field mappings
type="integer"> •Java Set for the Tracks
<generator class="identity" /> •Class on the many side
</id> •Foreign Key on the many
... side
<set name="Tracks" inverse="true"
cascade="all" lazy="false">
<one-to-many class="Track" />
<key
column="FK_CONFERENCE_ID" />
Association Mappings
Supported Associations
• One-to-one
– Maintained with Foreign Keys in Database
• One-to-many / Many-to-one
– Object on the ‘one’ side
– Collection on the many ‘side’
• Many-to-Many
– Use a ‘mapping’ table in the database
Association Mappings
Some Details

• Inverse attribute used for bi-directional associations


• Lazy Loading
– Configured per relationship
– Uses dynamic proxies at Runtime
• Cascading Styles
– “none” no operations are cascaded
– “all” all operations are cascaded
– Every operation in Hibernate has a corresponding cascade
style
Hibernate Query Language
HQL
• An objectified version of SQL
– Polymorphic Queries
– Object parameters in Queries
– Less verbose than SQL
• Doesn’t hide the power of SQL
– SQL joins, Cartesian products
– Projections
– Aggregation (max, avg) and grouping
– Ordering
– Sub-queries
– …and more
Hibernate Query Language
HQL
• Simplest HQL Query
– Return all Addresses

session = sessionFactory.openSession();
// query string – ‘Address’ refers to a Class not a Table
String queryString = "from Address";

// create, configure and execute the query


List addresses = session.createQuery(queryString).list();
Hibernate Query Language
HQL
• A more elaborate HQL Query
– Return all Tracks in a Conference

Conference conference = …
session = sessionFactory.openSession();
// build a query string
String queryString = “from Tracks as t where t.Conference = :conf”;
// create, configure and execute the query
List addresses = session.createQuery(queryString)
.setObject(“conf”, conference)
.list();
Hibernate Query Language
HQL Parameters
• Named parameters removed positional problems
• May occur multiple times in the same query
• Self-documenting

List tracks = new ArrayList();


tracks.add(“JSE");
tracks.add(“JEE");
Query q = session
.createQuery("from Sessions s where s.Track in (:trackList)");
q.setParameterList(“trackList", tracks);
List sessions = q.list();
Hibernate Query Language
HQL Parameters
• Specify bounds upon your result set
• The maximum number of rows
• The first row you want to retrieve

Query query = session.createQuery("from Users");


query.setFirstResult(50);
query.setMaxResults(100);
List someUsers = query.list();
Query by Criteria
• Same query using the Criteria API
– Return all Tracks for a given Conference

Conference conference = …
session = sessionFactory.openSession();

// create and expression to match the given conference


Expression exp = Expression.eq(“Conference", conference);

List addresses = session


.createCriteria(Tracks.class)
.add(exp)
.list();
Query by Example
• Return all Address for a given Street Name

Address address = new Address();


Address.setStreetAddress(“Main Street”);

// create example object


Example example = Example.create(address)
.ignoreCase()
.enableLike(MatchMode.ANYWHERE);

// create, configure and execute the query


List matches = session.createCriteria(Address.class)
.add(example)
.list();
Caching in Hibernate

• 1st Level
– Transaction scoped cache provided by the Session.
– Always available
• 2nd Level
– Process scoped cache
– Shared by all Sessions
– Optional
– Pluggable implementation, can be clustered
• Query
– Use with care, profile first
Caching in Hibernate
Caching in Hibernate

• Caching setting in HBM for Read Only

<class name=“ReferenceData”
table=“REFDATA”>
<cache usage=“read-only” />
..
</class>
Caching in Hibernate

• Caching setting in HBM for Read/Write


• Profile the application before applying

<class name=“ReadMostly”
table=“READMOSTLY”>
<cache usage=“nonstrict-read-write” />
..
</class>
Caching in Hibernate

• Query Caching, most difficult to get right


• Analyze/Profile First. Let usage determine which
queries to cache

String queryString = “from ...”;


List hits = session
.createQuery(queryString)
.setObject(“user”, user)
.setCacheable(true)
.list();
Other Hibernate Features
• Multiple Strategies for supporting Inheritance
• Scalar Query Results
• Projections
• Custom SQL for Loading, Updating and
Deleting
• J2EE/JTA Friendly
• Spring Integration
Conclusions
Why should you use Hibernate?
• It’s a well designed product. Look at the source!
• It covers 80% of your persistence needs and does a
fine job on the other 20%
• You get to work with POJOs, not coarse-grained
EJBs
• Performance is good! Boils down to the generated
SQL
– If you don’t like it, you can always use custom SQL
Conclusions
Why should you use Hibernate?
• Good separation of integration tier and the rest of the
application
• Avoid reinventing the well
• Good community support, large pool of talent
Let’s Look at some Code
Quick Live Demos
• Some CRUD Demos
• Inheritance Demo
– using Table-Per-Class-Hierarchy
• Hibernate Components
• Hibernate code in a J2EE app
Questions?
Thank you!
You can contact me with questions at
bsbodden@integrallis.com

Our website
http://www.integrallis.com

Updated Slides Online


Shameless Plug ;-)
get the book…
Shameless Plug ;-)
…so that I can feed him

You might also like