Object/Relational Mapping With Hibernate
Object/Relational Mapping With Hibernate
with Hibernate
Practical ORM
Who is this guy?
Gavin King
[email protected]
“Modern” ORM Solutions
Transparent Persistence (POJO/JavaBeans)
Persistent/transient instances
Automatic Dirty Checking
Transitive Persistence
Lazy Fetching
Outer Join Fetching
Runtime SQL Generation
Three Basic Inheritance Mapping Strategies
Why?
Natural programming model
Minimize LOC
Code can be run and/or tested outside the
“container”
Classes may be reused in “nonpersistent” context
Minimize database access with smart fetching
strategies
Opportunities for aggressive caching
Structural mapping more robust when
object/data model changes
Entity Beans?
Transparent Persistence
Persistent/transient instances
Automatic Dirty Checking
Transitive Persistence
Lazy Fetching
Outer Join Fetching
Runtime SQL Generation
Three Basic Inheritance Mapping
Strategies
What do RDBs do well?
Work with large amounts of data
Searching, sorting
Work with sets of data
Joining, aggregating
Sharing
Concurrency (Transactions)
Many applications
Integrity
Constraints
Transaction isolation
What do RDBs do badly?
Modeling
No polymorphism
Fine grained models are difficult
Business logic
Stored procedures kinda suck
Distribution
(arguable, I suppose)
Data is important
Even so, the relational model is
important…
The data will be around much longer
than the Java application!
The Goal
Take advantage of those things that
relational databases do well
Without leaving the language of
objects / classes
The Real Goal
Do less work
Happy DBA
Hibernate
Opensource (LGPL)
Mature
Popular (13 000 downloads/month)
Custom API
Will be core of JBoss CMP 2.0 engine
Hibernate
Persistence for JavaBeans
Support for very fine-grained, richly
typed object models
Powerful queries
Support for detached persistent
objects
Auction Object Model
Persistent Class
Default public class AuctionItem {
private Long _id;
constructor private Set _bids;
private Bid _successfulBid
Get/set pairs private String _description;
AuctionItem item =
(AuctionItem) session.get(ActionItem.class, itemId);
item.setDescription(newDescription);
tx.commit();
session.close();
Transitive Persistence
Retrieve an AuctionItem and create a new persistent Bid
AuctionItem item =
(AuctionItem) session.get(ActionItem.class, itemId);
bid.setItem(item);
item.getBids().add(bid);
tx.commit();
session.close();
Detachment
Retrieve an AuctionItem and create a new persistent Bid
item.setDescription(newDescription);
item.getSuccessfulBid().getAmount();
SELECT …
FROM AUCTION_ITEM ITEM
LEFT OUTER JOIN BID BID1 ON BID1.ITEM_ID = ITEM.ITEM_ID
LEFT OUTER JOIN BID BID2 ON BID2.BID_ID = ITEM.SUCCESSFUL_BID
WHERE ITEM.ITEM_ID = ?
Optimizing Data Access
Minimize row reads
Minimize database roundtrips
(Much less important) Minimize
column reads
Optimizing Data Access
Minimize row reads
Use lazy fetching
Minimize database roundtrips
Use outer join fetching
(Much less important) Minimize
column reads
Come back to this one later…
Optimizing Data Access
Minimize row reads
Use lazy fetching
• N+1 Selects Problem (too many
roundtrips)
Minimize database roundtrips
Use outer join fetching
• Cartesian Product Problem (huge result
set)
Optimizing Data Access
Solution: Runtime Fetch Strategies
1. Say what objects you need
2. Navigate the object graph
Hibernate Query Options
Hibernate Query Language (HQL)
“Minimal” OO dialect of ANSI SQL
Criteria Queries
Extensible framework for expressing query
criteria as objects
Includes “query by example”
Native SQL Queries
Hibernate Query Language
Make SQL be object oriented
Classes and properties instead of tables and columns
Polymorphism
Associations
Much less verbose than SQL
Full support for relational operations
Inner/outer/full joins, cartesian products
Projection
Aggregation (max, avg) and grouping
Ordering
Subqueries
SQL function calls
Hibernate Query Language
HQL is a language for talking about “sets of
objects”
It unifies relational operations with object
models
Hibernate Query Language
Simplest HQL Query:
from AuctionItem
select item
from AuctionItem item
join item.bids bid
where item.description like ‘hib%’
and bid.amount > 100
i.e. get all the AuctionItems with a Bid worth > 100 and
description that begins with “hib”
Hibernate Query Language
Projection:
i.e. get the description and amount for all the AuctionItems
with a Bid worth > 100
Hibernate Query Language
Aggregation:
Equivalent HQL:
Equivalent HQL:
Better encapsulation
Components
Address class
street, city, postCode properties
STREET, CITY, POST_CODE columns of
the PERSON and ORGANIZATION
tables
Mutable class
Components
<class name=“Person” table=“PERSON”>
…
<component name=“address”>
<property name=“street” column=“STREET”/>
<property name=“city” column=“CITY”/>
<property name=“postCode” column=“POST_CODE”/>
</component>
</class>
Custom Types
MonetoryAmount class
Used by lots of other classes
Maps to XXX_AMOUNT and
XXX_CURRENCY columns
Performs currency conversions
(behaviour!)
Might be mutable or immutable
Custom Types
<class name=“Bid” table=“BID”>
…
<property name=“amount” type=“MonetoryAmountUserType”>
<column name=“AMOUNT”/>
<column name=“CURRENCY”/>
</property>
</class>
item.setDescription(newDescription);
Detached Object Support
Step 3: Make the changes persistent, back in the
session bean:
http://www.andromda.org/