Java Persistence Framework

115
Hibernate Java persistence framework Copyright 2007 Jerry Kurian

description

A look at basics and advanced aspects of hibernate

Transcript of Java Persistence Framework

Page 1: Java Persistence Framework

Hibernate

Java persistence framework

Copyright 2007 Jerry Kurian

Page 2: Java Persistence Framework

About the author

� Jerry Kurian

� Profile http://www.linkedin.com/in/jerryk

� Has over 10 years of software development and training experience with expertise in distributed server development using Javadistributed server development using Java

� Worked for over 5 years in a leading telecom firm developing distributed J2EE app server

� Currently working as Chief architect and lead developer at CellZapp (www.cellzapp.com) a revolutionary product under development

Page 3: Java Persistence Framework

Modern architecture

� Most of the modern languages have embraced object oriented programming approach

� OOP based software architecture promotes separation of concerns such that each component does only what it is supposed to do

� Application development should mostly focus on problems in the application domain, which is the

� Application development should mostly focus on problems in the application domain, which is the business logic

� A highly scalable architecture is one with the least amount of direct dependence between components

Page 4: Java Persistence Framework

Persistence

� Persistence of information is one of the most basic requirements in a software application

� Almost all languages provide ways and methods to persist data

� J2EE has supported JDBC for persistence since its � J2EE has supported JDBC for persistence since its beginning

� JDBC has been useful but tends to not allow isolation of business logic and persistence concerns

Page 5: Java Persistence Framework

JDBC and separation of concerns

� Programming with JDBC requires usage of semantics of the database world

� JDBC code has its own rules and concerns, which are not really the concern of the business domain

� Writing simple JDBC code may be relatively easy, but for complex issues like caching and clustering, JDBC for complex issues like caching and clustering, JDBC does not offer anything

� JDBC code makes business logic developer worry about persistence issues.

Page 6: Java Persistence Framework

ORM (Object relational mapping)

� Relational databases have proved to be most effective at managing application data

� OOP on the other hand is the one best suited for implementing business logic and other aspects of applicationaspects of application

� ORM is an attempt to merge together the best of both worlds

Page 7: Java Persistence Framework

ORM (Object relational mapping)

� ORM aims to provide access to data in the form most familiar to the OOP developer, which is API

� ORM aims to enable the business logic developer deal with underlying persistence developer deal with underlying persistence only in terms of business entities.

� In most cases, ORM enables Java OOP programmer to only know deal in Java and no other language like SQL.

Page 8: Java Persistence Framework

Hibernate

� Hibernate is an open source ORM framework that is a pioneer and market leader

� Hibernate provides ORM solution which is compatible with the latest JPA specifications

� Provides transparent persistence, allowing the application to switch between database vendors or even persistence mechanismmechanism

� Provides complete separation of concerns between domain business logic and persistence

� No need to implement any hibernate specific interfaces, APIs or extend classes from within the domain objects

Page 9: Java Persistence Framework

Hibernate Architecture

� Applications make use of hibernate through the interfaces which it provides

� Hibernate makes itself accessible to the application at the following levels� Configuration (Allowing application to configure

hibernate) Persistence (Allowing application to persist its domain � Persistence (Allowing application to persist its domain object over a session in a transaction. Or to retrieve using queries)

� Callback (Allowing application to keep track of hibernate events)

� Extension (Allowing application to add UserTypes, IdentifierGenerator)

Page 10: Java Persistence Framework

Hibernate Architecture

Applic

atio

n L

ayer

Configuration Layer

HibernateExtensions

Callback Layer

Applic

atio

n L

ayer

Application Domain Objects (POJO)

Persistence LayerSession, Transaction, Query,

SessionFactory

Application Database

Callback Layer(Interceptor, Validatable, Lifecycle)

Dialect JDBC

Page 11: Java Persistence Framework

Hibernate Interfaces

� As described earlier the major interfaces of concern in hibernate are

� Session

� SessionFactory

� Configuration� Configuration

� Transaction

� Query

� Callback

� Types

� Extension

Page 12: Java Persistence Framework

Session Interface

� Primary interface used by application when interacting with hibernate

� Found in the package “org.hibernate”

� Light weight interface that acts as a persistence manager

� It is not thread safe and so should be used one per � It is not thread safe and so should be used one per thread

� Represents one unit of work. In web invocation terms, can be mapped to one client request

� The basic level of object cache in hibernate

Page 13: Java Persistence Framework

SessionFactory

� Acts as Factory to the Session objects

� SessionFactory used across the application

� One SessionFactory per database

� Can provide second level of cache for objects � Can provide second level of cache for objects across sessions

Page 14: Java Persistence Framework

Configuration

� Used for configuring the hibernate

� Provides access to the configured SessionFactory

TransactionTransaction� An optional API, applications can use its own

transaction infrastructure if desired

� Provides abstraction over lower level transaction implementation either via JDBC or JTA

Page 15: Java Persistence Framework

Query

� Used for querying database to retrieve objects� Provides way to set query parameters and limit result

size� Comes with a Criteria interface to filter search

CallbackCallback� Allows applications to keep track of the events

happening in hibernate

� Interceptor can be used to react to lifecycle events

Page 16: Java Persistence Framework

Types

� Hibernate Types map to the java types of the data stored in DB

� UserType and CompositeUserType can be used to add domain specific types to hibernate

ExtensionExtension� Allows extending hibernate functionalities

� Commonly used extension interfaces are IdentifierGenerator and Dialect

Page 17: Java Persistence Framework

Lifecycle of persistent object

� The application domain objects (POJO) are the persistent objects

� The persistence object can be in one of the three states

Transient� Transient

� Persistent

� Detached

Page 18: Java Persistence Framework

Lifecycle of persistent object

Garbage

Transientnew

get() load() find()

save() saveOrUpdate()

delete()

Garbage collectedPersistent

Detached

find() iterate()

evict() close() clear()

update() saveOrUpdate() lock()

()

Page 19: Java Persistence Framework

Transient Object

� Any application domain object created using a new() operator is a transient object and as such a plain java object

� Any state in such an object is not associated with any database table row

� If such an object is destroyed without becoming persistent, then no data held by the object is stored in

� If such an object is destroyed without becoming persistent, then no data held by the object is stored in the DB

� For an object to move from transient state to persistent state requires a call to save() method of the persistence manager

Page 20: Java Persistence Framework

Persistent Object

� An object with its database identifier set is a persistent object

� Persistent object is always part of a session and is transactional

A persistent object can be created by calling � A persistent object can be created by calling save() on the Persistence manager

� Persistent object might be an instance retrieved from DB using a query

Page 21: Java Persistence Framework

Persistent Object

� Persistent objects participate in transactions and its state is synchronized with the database at the end of transaction

� When transaction is committed, Persistent object is synchronized with DB using INSERT, UPDATE or DELETEDELETE

� Persistent object may also be synchronized with DB before execution of a query to get latest data from DB into memory

Page 22: Java Persistence Framework

Detached Object

� A domain object is persistent only in the scope of the session in which it was created

� If the session is closed using Session.close() then all persistent objects that are still referenced after close() are in detached state

� They are no longer associated with any transaction � They are no longer associated with any transaction and will not be synchronized with the database

� The data contained in such objects may not be the latest.

Page 23: Java Persistence Framework

Object Identity

� In Java, objects are often compared for equality using object identity (a==b)

� A persistent object may also require comparison of its database identifier, to establish identity.establish identity.

� Concept of transient, persistent and detached objects provides different scopes for objects within which there identities may differ

Page 24: Java Persistence Framework

Object Identity

� Hibernate supports Transaction-Identity scope

� If a persistent object is accessed multiple times within a same transaction, then hibernate ensures that the same instance is always returned

� This ensures that within a transaction, application works on the same dataworks on the same data

� Once a transaction is committed and a session is closed, the detached object is no longer in the transactional scope

Page 25: Java Persistence Framework

Object Identity

� Equality between to persistent objects can be best established by proper implementation of equals() method in the domain class

� Typical implementation of equals() method will be as followsbe as follows

public class Person {

public boolean equals(Object other){if(this==other)return true;if(id==null) return false;if(!(other instanceof Person)) return false;

Person person = (Person) other;return this.id.equals(person.getId());

}}

Page 26: Java Persistence Framework

Getting started with hibernateGetting started with hibernate

Page 27: Java Persistence Framework

Hello World

Table MessageCREATE TABLE Message (Message_ID INTEGER UNSIGNED NOT NULL

AUTO_INCREMENT,

� Create a table Message for the application

AUTO_INCREMENT,NextMessageID INTEGER UNSIGNED NULL,text VARCHAR(20) NULL,PRIMARY KEY(Message_ID),INDEX Message_FKIndex1(NextMessageID)

);

Page 28: Java Persistence Framework

Hello World� Create a domain class Message

package com.sample.hibernate.model;public class Message {

private Long id;private String message;

private Message(){}

public Message(String mes){message = mes;}

public Long getId() {return id;}

public void setId(Long id) {this.id = id;}

public Message getNextMessage() {return nextMessage;}

public void setNextMessage(Message nextMessage) {this.nextMessage = nextMessage;}

}

Page 29: Java Persistence Framework

Hello World� Create a class and property mapping file called

Message.hbm.xml. Place it in classpath

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping><hibernate-mapping><class name="com.sample.hibernate.model.Message"table="Message"><id name="id" column="Message_ID"><generator class="increment"></generator></id><property name="message" column="text"/><many-to-one name="nextMessage" cascade="all" column="NextMessageID"/></class></hibernate-mapping>

Page 30: Java Persistence Framework

Hello World� Create a DAO class

package com.sample.hibernate.dao;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;

import com.sample.hibernate.model.Message;public class MessageDAO {

public void createMessage(String msg){Session session = getSessionFactory().openSession();Transaction tx = session.beginTransaction();Message message = new Message(msg);

session.save(message);

tx.commit();

session.close();

}

private SessionFactory getSessionFactory() {// TODO Auto-generated method stubreturn new Configuration().

addResource("com/sample/hibernate/model/Message.hbm.xml").buildSessionFactory();

}

public static void main(String[] args){MessageDAO dao = new MessageDAO();dao.createMessage("Hello World");

}}

Page 31: Java Persistence Framework

Hello World� Create hibernate.properties file

hibernate.connection.driver_class=com.mysql.jdbc.Driverhibernate.connection.url=jdbc:mysql://localhost:3306/messagehibernate.connection.username=roothibernate.connection.password=hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect

� Add following jars to classpath� Add following jars to classpath� antlr-2.7.6.jar

� antlr.license.txt

� asm.jar

� cglib-2.1.3.jar

� commons-collections.jar

� commons-logging-1.1.jar

� dom4j-1.6.1.jar

� hibernate3.jar

� jta.jar

� jta.licence.txt

� mysql-connector-java-3.0.9-stable-bin.jar

� oscache-2.3.2.jar

Page 32: Java Persistence Framework

Hello World

� Run the app with main method in the DAO class.

� The data should be inserted in the database

Page 33: Java Persistence Framework

Relationships and associationsRelationships and associations

Page 34: Java Persistence Framework

Data relationships

� Most of the data found in application domain are related to each other

� Relational databases are efficient in mapping these relations using foreign keys

Using hibernate to map to such data from the � Using hibernate to map to such data from the object model requires special consideration

Page 35: Java Persistence Framework

Data relationships

� The types of relations typically observed in the relational database world are� One-to-One relationship� One-to-Many relationship� Many-to-Many relationship

Object associationsObject associations� In the world of OOP the relations between entities are

more commonly implemented using associations that can be� Composition� Inheritance

Page 36: Java Persistence Framework

One-to-One relations using foreign key

� The relational data can have a one-to-one relationship as can be seen between a person and his/her address

Page 37: Java Persistence Framework

One-to-One relations using foreign key

� In this case the domain object model will have a corresponding Person class referencing an Address object as a property

� When a Persistent instance of Person class is loaded, the persistent instance of its referenced loaded, the persistent instance of its referenced Address instance should also be loaded appropriately

� To enable this, the two classes should be mapped appropriately

Page 38: Java Persistence Framework

One-to-One relations using foreign key

package com.sample.hibernate.model;

public class Person {private int id;private Address billingAddress;private String name;

public boolean equals(Object

package com.sample.hibernate.model;

public class Address {

private String lane;private String city;private String state;

}public boolean equals(Object other){

if(this==other)return true;if(id==null) return false;if(!(other instanceof Person)) return false;Person person = (Person)

other;returnthis.id.equals(person.getId());

}}

}

Page 39: Java Persistence Framework

One-to-One relations using foreign key

� For foreign key association, hibernate does not distinguish between One-to-One and One-to-many relations and in this case we use the <many-to-one> tag for mapping the one-to-one relation

� In this example, the mapping file for Person class will have the following entry

<many-to-one name="billingAddress"class="com.sample.hibernate.mode.Address"column="Address_id"cascade="save-update"/>

Person.hbm.xml

Page 40: Java Persistence Framework

One-to-One relations using foreign

key-Bidirectional� In the above example, there is only one way navigation from

Person to Address.

� If we would like to go back to person instance from Address, then there should be a reference to Person in Address class, which will be mapped as follows

Address.hbm.xml

<one-to-one name=“person"class="com.sample.hibernate.mode. Person"property-ref=“billingAddress"/>

� This will ensure that the Address instance will hold reference to its appropriate Person instance so that bi-directional navigation can be achieved

Page 41: Java Persistence Framework

One-to-One relations using primary

key

� The one-to-one relation can also be established through primary key association

� The primary key will also act as a foreign key in this case

Page 42: Java Persistence Framework

One-to-One relations using primary

key� In this case it must be ensured that the newly created Address

objects have the same key as the Person for which it is created

� The mappings in this case will be

<one-to-one name="billingAddress"

Person.hbm.xml

<one-to-one name="billingAddress"class="com.sample.hibernate.mode.Address"

cascade="save-update"/>

<one-to-one name=“person"class="com.sample.hibernate.mode.Person"

constrained=“true"/>

� Constrained attribute tells hibernate that the Address has a foreign key constraint on its primary key and it refers to the Person primary key

Address.hbm.xml

Page 43: Java Persistence Framework

One-to-One relations using primary

key

� To ensure that newly saved Address instances are assigned the same primary key as that of the person, a special identifier-generator needs to be used

<class name="com.sample.hibernate.mode.Address" table="Address">

Address.hbm.xml

table="Address"><id name="id" column="Person_id" >

<generator class="foreign"><param

name="property">person</param></generator>

</id>

� The property “person” of the new Address object is used to get the identifier which is assigned to the Address identifier

Page 44: Java Persistence Framework

One-to-Many relations unidirectional

� The item table in an auction will have multiple bids placed on it, and will have a one to many relation

Page 45: Java Persistence Framework

One-to-Many relations unidirectional

� For unidirectional navigation, the item class will hold a collection of bids

� The relationship will be mapped using the <set> element

Item.hbm.xml

<set name="bids“ table=“Bid”><key column="Item_ID"/><one-to-many class="Bid"/></set>

Page 46: Java Persistence Framework

One-to-Many relations biderectional

� For bidirectional navigation, the bid class will hold the item for which the bid is created.

� The item property can be mapped as follows

<many-to-one name=“item"column="Item_ID“class=“Item”not-null=“true"/>

Bid.hbm.xml

Page 47: Java Persistence Framework

Many-to-Many relations unidirectional

� A many to many relation should ideally make use of a link table

� The link table will have foreign keys to the primary keys of the original table

Page 48: Java Persistence Framework

Many-to-Many relations unidirectional

� The category class in this case will hold reference to the Item in the form of collection of value types

<set name="items"

Category.hbm.xml

<set name="items"table="CATEGORY_ITEM"

lazy="true"cascade="save-update“>

<key column="category_id"/><many-to-many class="Item" column="Item_ID"/></set>

Page 49: Java Persistence Framework

Many-to-Many relations bidirectional

� Item class holds reference to categories

<set name=“categories"table="CATEGORY_ITEM"

lazy="true“

Item.hbm.xml

lazy="true“inverse=“true”cascade="save-update"

<key column=“Item_ID"/><many-to-many class=“Category" column=“Category_ID"/></set>

� The inverse=true attribute tells hibernate to synchronize changes done only to Category instances

Page 50: Java Persistence Framework

Advanced Mapping ConceptsAdvanced Mapping Concepts

Page 51: Java Persistence Framework

Hibernate type system

� When working with hibernate, we have to deal with two data types

� The data type of the underlying database

� The Java data types

� The Java types need to be mapped to the data types in the databasein the database

� In the mapping files, the types are mapped as follows� <property name=“email” column=“EMAIL”

type=“string”/>

Page 52: Java Persistence Framework

Hibernate type system

� When working with hibernate, we have to deal with two data types

� The data type of the underlying database

� The Java data types

� The Java types need to be mapped to the data types in the databasein the database

� In the mapping files, the types are mapped as follows� <property name=“email” column=“EMAIL”

type=“string”/>

Page 53: Java Persistence Framework

Built-in mapping types

� Hibernate comes with in built-in mapping types for various java and SQL types

SMALLINTShort or java.lang.ShortShort

BIGINTLong or java.lang.LongLong

INTEGERInt or java.lang.Integerinteger

SQL typeJava typeMapping type

CHAR(1) (‘T’ or ‘F’) Boolean or java.lang.BooleanTrue_false

CHAR(1) (‘Y’ or ‘N’) Boolean or java.lang.BooleanYes_no

BITBoolean or java.lang.BooleanBoolean

TINYINTByte or java.lang.ByteByte

VARCHARJava.lang.StringString

CHAR(1) Java.lang.StringCharacter

NUMERICJava.math.BigDecimalBig_decimal

DOUBLEDouble or java.lang.DoubleDouble

Page 54: Java Persistence Framework

Built-in mapping types

� The built in data type for dates and times are

TIMEJava.util.Date or java.sql.TimeTime

DATEJava.uti.Date or java.sql.DateDate

SQL typeJava typeMapping type

DATEJava.util.CalendarCalendar_date

TIMESTAMPJava.util.CalendarCalendar

TIMESTAMPJava.util.Date or java.sql.Timestamp

Timestamp

Page 55: Java Persistence Framework

Built-in mapping types

� The built in data type for large object mappings are

CLOBJava.sql.ClobClob

VARBINARY (or BLOB) Any java class that implements Serializable

Serializable

CLOBJava.lang.StringText

VARBINARY (or BLOB) Byte[]Binary

SQL typeJava typeMapping type

BLOBJava.sql.BlobBlob

CLOBJava.sql.ClobClob

� The java.sql.Blob or java.sql.Clob may be the most efficient way of handling large objects

� But these may not be supported by drivers for all databases

� If a Blob or Clob is referenced in a persistent class, then they will only be available in a transaction and not when it is in detached state

Page 56: Java Persistence Framework

Mapping inheritance

� Inheritance is a very powerful OOP concept and is used quite often in applications

� Relational database does not support inheritance. It only establishes relations using foreign keysforeign keys

� For scenarios where the application domain object has an inheritance type of relationship, there are a few things to be considered while creating the mapping

Page 57: Java Persistence Framework

Mapping inheritance

� Consider a case where an application has multiple billing options� Credit card

� Bank account

� In this case, the user name and details a re same, only the type specific details differthe type specific details differ

CreditCardType:int

expMonth:StringexpYr:String

BankAccount

Name:StringSwift:string

BillingDetailsOwner:Stringnumber:StringCreated:Date

Page 58: Java Persistence Framework

Mapping inheritance

� One of the strategies that can be applied is Table per concrete class

� In this case, the user name and details are same, only the type specific details differ

� This is a little inefficient as two queries are needed to fetch the details

Page 59: Java Persistence Framework

Mapping inheritance

� Another strategy that can be applied is table per hierarchy

� A single table representing all the details

� Although there is a single table the classes will still be separate

Page 60: Java Persistence Framework

Mapping inheritance

� The mappings for the table per hierarchy will make use of the <subclass> element

� This approach requires all properties of Credit card and bank details to be nullable.

<hibernate-mapping><class name="BillingDetails"table="BillingDetails">table="BillingDetails"><id name="id" column="BillingDetailsId"><generator class="increment"></generator></id><descriminator column=“BILLINGTYPE” /><subclass name="CreditCard" discriminator-value="CC"><property name=“ccnumber" column=“number"/></subclass></class>

</hibernate-mapping>

Page 61: Java Persistence Framework

Mapping inheritance

� Another strategy that can be applied is table per subclass

� The tables contain only the required columns and a foreign key to the BillingDetails

� The foreign key also acts as the primary key of the table

Page 62: Java Persistence Framework

Mapping inheritance

� A <joined-subclass> element is used to indicate table-per subclass mapping

<class name="BillingDetails"table="Billing_Details"><id name="id" column="id"><generator class="increment"></generator><generator class="increment"></generator></id>

<joined-subclass name="CreditCard" table="CreditCardDetails"><key column="Billing_Details_Id"/><property name="cctype" column="cctype"/>

</joined-subclass></class>

Page 63: Java Persistence Framework

Basic QueriesBasic Queries

Page 64: Java Persistence Framework

Queries

� Queries are most important for writing good data access code

� Hibernate provides extensive support for querying using its Query interface

Queries are in terms of classes and � Queries are in terms of classes and properties and not tables and columns

� Hibernate also supports execution of native SQL queries

Page 65: Java Persistence Framework

Queries

� Queries can be created on a session

� Query hqlQuery = session.createQuery(“from Person”);

� Queries support pagination by limiting results

� Query query = session.createQuery(“from � Query query = session.createQuery(“from User”);

� Query.setFirstResult(0);

� Query.setMaxResults(10);

Page 66: Java Persistence Framework

Queries

� Queries support criteria for filtering searches based on criteria

� Session.createCriteria(Category.class).add(Expression.like(“name”, “Laptop%”));

� List() method executes the created query and � List() method executes the created query and returns the results as a list

� List result = session.createQuery(“from User”).list();

Page 67: Java Persistence Framework

Named Queries

� Named queries help in avoiding HQL queries to be located within Java files

� The queries to be used in an application can be externalized in an XML mapping file

The desired query can be referred to by the � The desired query can be referred to by the name

Page 68: Java Persistence Framework

Named Queries

� getNamedQuery() method obtains a Query instance from a named query

session.getNamedQuery("findItemsByDescription").

setString("description", description).list();setString("description", description).list();

<query name="findItemsByDescription"><![CDATA[from Item item where item.description like :description]]></query>

� Named queries allow easier optimization of queries

Page 69: Java Persistence Framework

Advanced QueriesAdvanced Queries

Page 70: Java Persistence Framework

The query API

� The Query interface of hibernate is used for retrieving the data from database

� Criteria interface is for specifying query criteria

� Query hquery = session.createQuery()

Criteria crit = session.createCriteria() � Criteria crit = session.createCriteria()

Page 71: Java Persistence Framework

Binding Parameters

� For passing parameters to a query, the following approaches can be used� Named Parameter

� Positional Parameter

� Named ParameterAllows you to specify the name of the expected parameter� Allows you to specify the name of the expected parameter

� String query = “from Item where description like :searchString”

� In this case “searchString” is the named parameter

� Query qu = session.createQuery(query).setString(“searchString”, searchString);

Page 72: Java Persistence Framework

Binding Parameters

� Positional Parameter

� Allows you to specify the parameter position using “?” like prepared statements

� String query = “from Item item where item.description like ? And item.date > ?”like ? And item.date > ?”

� Query qu = session.createQuery(query).setString(0, searchString).setDate(1,minDate);

Page 73: Java Persistence Framework

Binding Parameters

� As seen in the above examples, the setString() and setDate() methods were used, Hibernate also allows setting of various other types as well as entity

� Session.createQuery(“from item where item.seller � Session.createQuery(“from item where item.seller = :seller”).setEntity(“seller”, seller);

Page 74: Java Persistence Framework

Ordering query results

� For ordering the results obtained from queries, hibernate provides order by clause

� “from User u order by u.username”

� “from User u order by u.username desc”

� The Criteria API also provides ordering

� Session.createCriteria(User.class).addOrder(Order.asc(“lastname”));

Page 75: Java Persistence Framework

Association

� The hibernate query language supports performing queries on associations

� Join can be used to combine data in two (or more) relations

� HQL provides four ways of expressing joins� HQL provides four ways of expressing joins

� An implicit association join

� An ordinary join in the from clause

� A fetch join in the from clause

� A theta-style join in the where clause

Page 76: Java Persistence Framework

Implicit association

� HQL supports multipart property paths for querying

From User u where u.address.city=“city”

Session.createCriteria(User.class).

add(Expression.eq(“address.city”,”city”));

Page 77: Java Persistence Framework

Association

� A fetch join can be used to specify that an association should be eagerly fetched

From Item itemFrom Item item

join item.bids b

Where b.price > ?

Page 78: Java Persistence Framework

Association

� An alias can be used to make query less verbose

From Item item

join fetch item.bids b

Where b.bidder.address.city like :city;Where b.bidder.address.city like :city;

Session.createCriteria(Item.class).

setFetchMode(“bids”, FetchMode.EAGER).

list()

Page 79: Java Persistence Framework

Theta Style Join

� Theta style joins are to perform joins between two un-associated classes

From user , category

� This will return an Object[] with 2 elements

Page 80: Java Persistence Framework

Aggregation

� The hibernate query language supports performing various aggregation of the results

� The supported aggregation functions are

� avg(...), sum(...), min(...), max(...)

count(*) count(...), count(distinct ...) � count(*) count(...), count(distinct ...)

� count(all...)

� Select count(*) from Item

� Select sum(amount) from Bid

Page 81: Java Persistence Framework

Grouping

� Any property or alias appearing in an HQL outside the aggregate function can be used for grouping results

� Select u.lastname, count(u) from User u group by u.lastname

� Here the results will be grouped according the user’s � Here the results will be grouped according the user’s lastname

� Grouping can be restricted using the having clause

� Select u.lastname, count(u) from User u group by u.lastname having user.lastname like ‘A%’

Page 82: Java Persistence Framework

Sub-queries

� In the databases that support sub-selects, hibernate supports sub-queries

� Sub-queries allow a select query to be embedded in another query

� From User u where 10 < (select count(i) from � From User u where 10 < (select count(i) from u.items I where i.successfulBid is not null)

� This returns all the users who have bid successfully more than 10 times

Page 83: Java Persistence Framework

Native queries

� Hibernate provides support for making use of native SQL queries instead of HQL

� The SQL query results return the entity instance just like hibernate queries

Page 84: Java Persistence Framework

Native queries

� SQL query may return multiple entity instances

� SQL query may return multiple instances of same entity

� Hibernate needs to distinguish between different entitiesentities

� Hibernate uses a naming scheme for the result column aliases to correctly map column values to the properties of particular instances

Page 85: Java Persistence Framework

Scalar Queries

� SQL queries can be used to return a list of scalars

String sql = “select * from appuser”ses.createSQLQuery(sql)

.addScalar("username", Hibernate.STRING) .addScalar("username", Hibernate.STRING)

.addScalar("name",Hibernate.STRING)

.list();

� This will return the scalar values as List of Object[]

Page 86: Java Persistence Framework

Entity Queries

� Hibernate can also allow you to obtain Entity instances using SQL queries

� The SQL queries will need to be supplied with the Entity that represents the table

String sql = “Select * from address”;String sql = “Select * from address”;

Session.createSQLQuery(sql).

addEntity(Address.class);

Page 87: Java Persistence Framework

Handling associations

� When an entity has a many-to-one relation with another, then it is required to return the association or else a column not found error will be returned

� A * notation will return the association� A * notation will return the associationString sql = "select * from appuser";

ses.createSQLQuery(sql).

addEntity(Appuser.class).

list();

Page 88: Java Persistence Framework

Returning Non-Managed entities

� SQL can be used to return non-managed entities� The entity instances returned may not reflect the

latest values over a sessionString sql = "select lane, city from address

where city like ?";

ses.createSQLQuery(sql) .setResultTransformer(Transformers.aliasToBean(Address.class)).setString(0, name) .list();

Page 89: Java Persistence Framework

Named SQL Query

� SQL queries can be written externally and accessed in the code

� Named queries allow more flexibility to modify queries

<sql-query name="cityQuery">

<return-scalar column="city" type="string"/>

<return-scalar column="lane" type="string"/><return-scalar column="lane" type="string"/>

<![CDATA[

SELECT a.city AS city,

a.lane AS lane

FROM Address a WHERE a.city LIKE :cityName

]]>

</sql-query>

Page 90: Java Persistence Framework

Stored Procedure

� Hibernate 3 introduces support for queries via stored procedures and functions

� The stored procedure/function must return a resultset as the first out-parameter to be able to work with Hibernate.to work with Hibernate.

Page 91: Java Persistence Framework

Stored Procedure

CREATE OR REPLACE FUNCTION selectAllEmploymentsRETURN SYS_REFCURSORASst_cursor SYS_REFCURSOR;

BEGINBEGINOPEN st_cursor FORSELECT EMPLOYEE, EMPLOYER,STARTDATE, ENDDATE,REGIONCODE, EID, VALUE, CURRENCYFROM EMPLOYMENT;

RETURN st_cursor;END;

Page 92: Java Persistence Framework

Stored Procedure

� To use the stored procedure, map it through a named query<sql-query name="selectAllEmployees_SP" callable="true">

<return alias="emp" class="Employment"><return-property name="employee" column="EMPLOYEE"/><return-property name="employer" column="EMPLOYER"/><return-property name="startDate" column="STARTDATE"/><return-property name="endDate" column="ENDDATE"/><return-property name="regionCode" column="REGIONCODE"/><return-property name="regionCode" column="REGIONCODE"/><return-property name="id" column="EID"/><return-property name="salary"><return-column name="VALUE"/><return-column name="CURRENCY"/></return-property></return>{ ? = call selectAllEmployments() }

</sql-query>

Page 93: Java Persistence Framework

Custom SQL

� Hibernate3 can use custom SQL statements for create, update, and delete operations

� The class and collection persisters in Hibernate already contain a set of configuration time generated strings (insertsql, deletesql, updatesql etc)

� The mapping tags <sql-insert>, <sql-delete>, and <sql-update> override these strings

Page 94: Java Persistence Framework

Custom SQL

� The custom SQL script can also invoke a stored procedure if any

� <sql-insert callable="true">{call createUser (?, ?)}</sql-insert>

<sql-delete callable="true">{? = call � <sql-delete callable="true">{? = call deleteUser (?)}</sql-delete>

� The positioning of parameters are important and should be as per what hibernate expects

Page 95: Java Persistence Framework

Hibernate TransactionsHibernate Transactions

Page 96: Java Persistence Framework

Transaction

� Most enterprise applications working with the database systems need to make use of transactions for data integrity

� In an application program, the data base transactions should be of as short duration as possible

� Ideally, the transaction should be in affect when the application is dealing with the DB and not when it is interacting with the user

Page 97: Java Persistence Framework

Transaction

� Java through JDBC and J2EE though JTA have provided powerful support for transactions

� Hibernate acts as a client to the JDBC and JTA transactions, allowing the application to JTA transactions, allowing the application to make use of the features while not worrying about the technical complexities

Page 98: Java Persistence Framework

Hibernate transaction API

� The Transaction interface of hibernate provides methods to define the transaction boundaries

� The transaction is created on the session� Transaction tx = session.beginTransaction();

� The commit() method makes performs the database commitcommit� tx.commit()

� In case of failure, rollback() method should be used to rollback the changes� tx.rollback()

Page 99: Java Persistence Framework

Flushing hibernate session

� Changes made to persistent object in a session are stored in memory

� Session implements transaction write behind whereby the changes are written to DB in a transparent manner and to reduce DB access

� Flushing of state occurs in the following cases

� When a transaction is committed

� Before a query is executed

� When application calls session.flush()

Page 100: Java Persistence Framework

Transaction Isolation levels

� The transaction isolation levels attempt to segregate concurrent transactions and their view of the data base state

� The isolation levels are implemented by the database vendors, either using locking or database vendors, either using locking or multi-version concurrency control

� Hibernate makes use of the underlying database implementation and does not on its own does not add any symantics

Page 101: Java Persistence Framework

Optimistic locking in application

� Most enterprise applications prefer to use optimistic locking

� Optimistic locking assumes there won’t be any conflicts and data will not be updated simultaneouslysimultaneously

� Optimistic locking can be implemented by using Version number or TimeStamp

Page 102: Java Persistence Framework

Optimistic locking in application

� When using Version, a column should be added to the table and mapped to a property in the POJO class

<version name=“version” column=“VERSION” /><version name=“version” column=“VERSION” />

� Whenever the object is changed, hibernate will automatically update the version number

Page 103: Java Persistence Framework

Optimistic locking in application

� When a transaction retrieves an object, its version number is also fetched

� While the object is in detached state, if the corresponding record is updated by another transaction, then the version number in the detached object will be olderobject will be older

� Any update issued for this detached object will result in failure since the update query will check for the current version in table to be same as the version number in the detached instance, which will fail with StaleObjectStateException

Page 104: Java Persistence Framework

Hibernate ExtensionHibernate Extension

Page 105: Java Persistence Framework

Custom mapping types

� Hibernate allows creation of custom value types for the application domain

� Some of the data in the database may be stored within multiple columns, but in the object model it may be better to represent it as a class

Example, For a multi currency payment system, the data � Example, For a multi currency payment system, the data may be stored as

Page 106: Java Persistence Framework

Custom mapping types� It may be desirable that the amount is always

represented in the same currency, say USD in a separate class like MonetaryAmount

package com.sample.hibernate.model;

import java.math.BigDecimal;

public class MonetaryAmount {

private final BigDecimal value;private final Currency currency;public MonetaryAmount(final BigDecimal value, final Currency cur) {super();this.value = value;this.currency = cur;}public Currency getCurrency() {return currency;}public BigDecimal getValue() {return value;}

}

Page 107: Java Persistence Framework

Custom mapping types

� To implement a custom user type, the type class needs to implement the interface org.hibernate.usertype.UserType

package com.sample.hibernate.model;

import java.math.BigDecimal;import java.math.BigDecimal;

public class MonetaryAmountUserType implements UserType {

}

� Of the various methods in the interface, the important ones are the nullSafeGet(ResultSet arg0, String[] arg1, Object arg2), where the value can be obtained from the resultset and the conversion to USD performed

Page 108: Java Persistence Framework

Custom mapping types

� To property with the custom type can now be mapped in the class as below

� <property name=“amount” column=“Amount” type=“com.sample.hibernate.model. MonetaryAmountUserType”/>MonetaryAmountUserType”/>

Page 109: Java Persistence Framework

CachingCaching

Page 110: Java Persistence Framework

Hibernate Cache

� One of the benefits of using Hibernate is its ability to cache the instances

� Cashing of data in entity instances can provide great performance benefits

� Hibernate provides configurable caching, where � Hibernate provides configurable caching, where each class can be separately enabled for caching depending on its usage

� Hibernate provides caching at multiple leves

Page 111: Java Persistence Framework

Hibernate Cache architecture

Session

First Level Cache

Cache

Second Level Cache

CacheStrategy

Query Cache

Cache Provider

Page 112: Java Persistence Framework

Hibernate Cache Architecture

� The hibernate cache provides caching at two levels

� The first level cache is the Session Cache which is enabled by default and can not be disabled

� The second level cached can be chosen � The second level cached can be chosen between

� Process Cache

� Clustered Cache

Page 113: Java Persistence Framework

First Level Cache

� All the persistence instances that are in Persistent state stay in the First Level Cache

� Changes made in a unit of work are cached in the first level cache

� Changes made to object are written to DB only on flush()

� You can opt to not keep data in first level cache by using � You can opt to not keep data in first level cache by using evict() method

� Not useful for application that deal with bulk or large quantity of data. In such case, we are better off using plain SQL or stored procedures

Page 114: Java Persistence Framework

Second Level Cache

� The second level cache is at a higher level and allow data to be shared across the application if opting for Process cache

� The cluster cache is across multiple servers and relies on remote communication to synchronize relies on remote communication to synchronize the cache

� The second level cache stores data in the form of Values

Page 115: Java Persistence Framework

Second Level Cache

� A cache provider can be configured in hibernate.cfg.xml<hibernate-configuration>

<session-factory>

<property name="hibernate.cache.provider_class">

org.hibernate.cache.EHCacheProvider

</property></property>

</session-factory>

</hibernate-configuration>

� A Class can be enabled for caching by indicating it in the mapping file

<class name="BillingDetails"table="Billing_Details"><cache usage="read-write"/>