Você está na página 1de 52

An Introduction to Hibernate

By Mr.Subrahmanyabharathi Pendyala Tata Consultancy Services Ltd Hyderabad.

Agenda
What is Hibernate

Overview Features Benefits Examples Important Concepts Best Practices

Spring Integration

Benefits Example

What is Hibernate?
Popular Open Source Object/Relational Mapping (ORM) tool Transparent persistence for POJOs (Plain Old Java Objects) Core of JBoss CMP 2.0 impl.

Features
Mapping from Java classes to database tables (and from Java data types to SQL data types). Data query and retrieval facilities. Generates the SQL calls and relieves the developer from manual result set handling and object conversion Portable to all data bases Provides persistence for Plain Old Java Objects(POJO)

Features
Support for detached persistent objects Powerful yet Simple queries using HQL.

Why should you use it


EJB (2.x)
Developer has to write EJB QL for CMP or native SQL for BMP. Database dependent Doesnt support OO mapping concepts Developer may not able to write optimal query, less performance

Hibernate
Hibernate generates query called HQL Data base independent Supports OO concepts like, Inheritance and Polymorphic mappings HQL is gives optimal query and gives more performance

Why should you use it


EJB(2.x)
y EJB container is required to

Hibernate
y No specific container needed y Hibernate components are

run the EJB s y EJB s are distributed components y EJB s can be invoked remotely

not distributed y Can't be invoked remotely

Why Hibernate?
Retains natural object model (transparent) Minimizes Code Does not require a container Model is not tied to persistence implementation

What to do RDBs do well Work with large amounts of data

Work with sets of data

Searching, sorting

Sharing

Joining, aggregating Concurrency (Transactions) Many applications Constraints Transaction isolation

Integrity

What to do RDBs do badly


Modeling

No polymorphism Fine grained models are difficult Stored procedures. (arguable, I suppose)

Business logic

Distribution

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

Sample OR Mapping file


<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernatemapping-3.0.dtd"> <hibernate-mapping>
<class name="events.Event" table="EVENTS"> <id name="id" column="EVENT_ID"> <generator class="native"/> </id> <property name="date" type="timestamp" column="EVENT_DATE"/> <property name="title"/> </class>

</hibernate-mapping>

How does it handle Database Connectivity


Hibernate configuration XML file <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernateconfiguration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- Database connection settings --> <property name="connection.driver_class">org.hsqldb.j dbcDriver</property> <property

How does it handle database connectivity


<!-- SQL dialect --> <property name="dialect">org.hibernate.dialect.HSQLD ialect</property> <!-- Enable Hibernate's automatic session context management --> <property name="current_session_context_class">thre ad</property> <!-- Disable the second-level cache --> <property name="cache.provider_class">org.hibernate. cache.NoCacheProvider</property> <!-- Echo all executed SQL to stdout -->

Object/Relational Mapping
JavaObject
int id; String name; String getName() int getId() void setName(String) void setId(int)

SQL Table id [int] primary key, name [varchar(50)]

Magic Happens Here (O/R Mapper i.e. Hibernate)

Other ORM Solutions


Open
iBatis SQL Maps JDO

Commercial
TopLink

Hibernate's Goal
Remove 95% of common data persistence problems

Person.java

Hibernate Component Mapping Example

person.hbm l .xm

person table

Nam e.java

Hibernate Collection M apping w ith recursion and subclassing


Cat.java cat.hbm.xml

cats

table

OR Mapping Made easy


Visualize the object model in terms of relationships. Write the Java classes for each object in the model. Add relevant Xdoclet tag to the code at the appropriate places. Use the relevant ant targets in the ant script to generate the mapping XML files for OR mapping. If the script is intelligent enough, you can also create database schema

How to Relationships of Object Model

Microsoft Word Document

Sample Build Script

XML Document

How do you use it?


Act on your data model Query in SQL and/or HQL ... or using your object model

Auction Object Model

Persistent Class
Default Constructor Getters/Setters Collections use interface types Identifier property
public class AuctionItem { private Long _id; private Set _bids; private Bid _successfulBid private String _description; public Long getId() { return _id; } private void setId(Long id) { _id = id; } public String getDescription() { return _description; } public void setDescription(String desc) { _description=desc; } }

XML Mapping
<class name=AuctionItem table=AUCTION_ITEM> <id name=id column=ITEM_ID> <generator class=native/> </id> <property name=description column=DESCR/> <many-to-one name=successfulBid column=SUCCESSFUL_BID_ID/> <set name=bids cascade=all lazy=true> <key column=ITEM_ID/> <one-to-many class=Bid/> </set> </class>

Readable metadata Column/Table map Key Generation Collections Fetching Strategies

Working with Data


Retrieve an AuctionItem and change description
Session session = sessionFactory.openSession(); Transaction tx = s.beginTransaction(); AuctionItem item = (AuctionItem) session.get(ActionItem.class, itemId); item.setDescription(newDescription); tx.commit(); session.close();

Working with Data


Retrieve an AuctionItem and create a new persistent Bid
Bid bid = new Bid(); bid.setAmount(bidAmount); Session session = sf.openSession(); Transaction tx = session.beginTransaction(); AuctionItem item = (AuctionItem) session.get(ActionItem.class, itemId); bid.setItem(item); item.getBids().add(bid); tx.commit(); session.close();

Hibernate in code
Retrieve an AuctionItem and create a new persistent Bid
Bid bid = new Bid(); bid.setAmount(bidAmount); Session session = sf.openSession(); Transaction tx = session.beginTransaction(); AuctionItem item = (AuctionItem) session.get(ActionItem.class, itemId); bid.setItem(item); item.getBids().add(bid); tx.commit(); session.close();

Working with detached objects.


Retrieve an AuctionItem and create a new persistent Bid
Session session = sf.openSession(); Transaction tx = session.beginTransaction(); AuctionItem item = (AuctionItem) session.get(ActionItem.class, itemId); tx.commit(); session.close(); item.setDescription(newDescription); Session session2 = sf.openSession(); Transaction tx = session2.beginTransaction(); session2.update(item); tx.commit(); session2.close();

Lazy Fetching
AuctionItem item = (AuctionItem) session.get(ActionItem.class, itemId); SELECT FROM AUCTION_ITEM ITEM WHERE ITEM.ITEM_ID = ? Iterator iter = item.getBids().iterate(); SELECT FROM BID BID WHERE BID.ITEM_ID = ? item.getSuccessfulBid().getAmount(); SELECT FROM BID BID WHERE BID.BID_ID = ?

DTOs are Evil


Useless extra LOC Not objects (no behavior) Parallel class hierarchies smell Shotgun change smell Solution: detached object support

Detached Object Support


For applications using servlets + session beans You dont need to select a row when you only want to update it! You dont need DTOs anymore! You may serialize objects to the web tier, then serialize them back to the EJB tier in the next request Hibernate lets you selectively reassociate a subgraph! (essential for performance)

Detached Object Support

Step 1: Retrieve some objects in a session bean:

public List getItems() throws { return getSession() .createQuery(from AuctionItem item where item.type = :itemType)

Detached Object Support


Step 2: Collect user input in a servlet/action:

item.setDescription(newDescription);

Detached Object Support


Step 3: Make the changes persistent, back in the session bean:

public void updateItem(AuctionItem item) throws { getSession().update(item); }

Transitive Persistence
Session session = sf.openSession(); Transaction tx = session.beginTransaction(); AuctionItem item = (AuctionItem) session.get(ActionItem.class, itemId); tx.commit(); session.close(); Bid bid = new Bid(); bid.setAmount(bidAmount); bid.setItem(item); item.getBids().add(bid); Session session2 = sf.openSession(); Transaction tx = session2.beginTransaction(); session2.update(item); tx.commit(); session2.close();

The Big Problem


Detached objects + Transitive persistence! How do we distinguish between newly instantiated objects and detached objects that are already persistent in the database?

The Big Problem (solution)


1.

Version property (if there is one) Identifier value e.g. unsaved-value=0 (only works for generated surrogate keys, not for natural keys in legacy data) Write your own strategy, implement Interceptor.isUnsaved()

2.

3.

Benefits
Metadata controlled persistence Transparent - working with the model, not the data access technology Pooling, Caching, Transactions can all be handled outside of our code

Integrating Spring and Hibernate

Spring and Hibernate


Benefits Examples

Benefits
Resource Management
IoC / AOP Session Management

Extended Transaction Support


JTA and/or JDBC Flexible Transaction Demarcation
Programmatic Declarative (Spring's XML config)

HibernateTemplate
Simplifies Hibernate API

Spring IoC
Session
setSession()

DAO
save()

POJO

Spring Interceptors (AOP)


Business Logic
getCatById()

Interceptor

DAO

save(Cat)

Session

Spring Framework

Springs HibernateTemplate
Hibernate Only:
public User getUserByEmailAddress(final String email) { try { Session session = sessionFactory.openSession(); List list = session.find( "from User user where user.email=?", email, Hibernate.STRING); return (User) list.get(0); } finally { session.close(); } }

HibernateTemplate:
public User getUserByEmailAddress(final String email) { List list = getHibernateTemplate().find( "from User user where user.email=?", email, Hibernate.STRING); return (User) list.get(0); }

Some Important Concepts


Lazy Loading --Getting the objects when needed
Eager Loading Getting it the first time when you hit the database Difference between load and get methods Load() --- Retrieves the objects from the Persistence Context , only if not available, database will be hit. Get() Retrieves from database. Fetch Strategies Inheritance strategies  Separate tables (implicit polymorphism) Ideally not preferred. Redundancy creeps in. Table Per class hierarchy (with discriminator column) Use it when data size is small  Normalized tables ( Good when working with large data)

Some Important Concepts


Transient Persistence (Persistence works similarly for transient , detached , attached objects) Detached Object support Optimistic locking ( through version fields preferably integers) Pessimistic locking ( using session.lock() method) Batch operations and best practices Sub selects ,Pre defined batch size Persistence Context ( Maintains cache of retrieved objects) SessionFactory( Thread safe) & Session (Not thread safe)
Object states and lifecycle Transient, Persistent, Detached, Removed

Important Links
http://www.hibernate.org http://www.springframework.org
Parts of this presentation come from documentation and presentations on the hibernate.org website:
http://www.hibernate.org/hib_docs/reference/en/pdf/hibernate_reference.pdf - Manual http://www.hibernate.org/hib_docs/online/jaoo_presentation/HibernateJAOO.ppt - Presentation by Gavin King http://www.hibernate.org/200.html - Road Map

Tutorials: http://raibledesigns.com/wiki/Wiki.jsp?page=CreateDAO http://raibledesigns.com/wiki/Wiki.jsp?page=AppFuseQuickStart

THANK YOU

Você também pode gostar