Hibernate Notes - baixardoc

10
Hibernate Notes & Interview Questions-Answers 1

Transcript of Hibernate Notes - baixardoc

Hibernate

Notes

&

Interview

Questions-Answers

1

HISTORY OF HIBERNATE

Hibernate was started in 2001 by Gavin King as an alternative to using EJB2-style Entity Beans. Its mission back then was to simply offer better persistence capabilities than offered by EJB2 by

simplifying the complexities and allowing for missing features.

Early in 2003, the Hibernate development team began Hibernate2 releases which offered many significant improvements over the first release and would go on to catapult Hibernate as the "de

facto" standard for persistence in Java.

The current version of Hibernate is Version 3.x. This version introduced new features like a newInterceptor/Callback architecture, user defined filters, and JDK 5.0 as of 2010 Hibernate 3 (version

3.5.0 and up) is a certified implementation of the Java Persistence API 2.0 specification via awrapper for the Core module which provides conformity with the JSR.

HIBERNATE--------------

Hibernate is a Persistence Framework is used to implement persistence logic or database

operations.

Hibernate is the King among all the persistence Framework like JPA, IBatis, TopLink, JDO

etc.

Architecture of Hibernate is Gavin King (from Redhat).

Hibernate is a ORM (Object Relational Mapping) Tool or Framework which simplifies the

Persistence Operations.

When we are implementing persistence logic with JDBC, we need to write the following code :try{

get the Connection(DataManager/DataSource);create the required Statement (Statement, PreparedStatement, CallableStatement);

prepared the SQL Statementsubmit the query to database (executeXX())

process the result}

catch(Exception e){Handling the Exception

}finally{

cleanup}

@ In the case of JDBC, we are responsible for write the code for all the above said operations

across the multiple programme.

@ Some JDBC statements are common like load the DataBase, Connection through DriverManager,

catch the Exception and close the all Connection (1, 2, 3, 5, 7) are common across the multipleprogram which gives us the code duplication problem.

@ In the case of JDBC, we are responsible take the required resources and close the resources

after using. If we are not closing the resources that may impact the application performance.

@ In the case of JDBC, we are responsible to write SQL statements, If SQL statements are not well-tuned that may also impact the application performance.

We write the Hibernate in two ways :

--------------------------------------------Hibernate 3.1 – Core (XML Based)

Hibernate 3.2 – Annotation (XML Based)

2

Hibernate Features :------------------------

1. Hibernate System responsible for taking the Connections, creating Statement and releasing the resources.

2. Hibernate support various Mapping Styles :i. Simple Mapping

ii. Collection Mappingiii. Inheritance Mapping

[a] Table per sub-class Mapping[b] Table per class Mapping

[c] Table per concrete class Mappingiv. Association Mapping

[a] One-to-One Mapping[b] One-to-Many Mapping

[c] Many-to-Many Mappingv. Other Mapping.

3. Hibernate Supports two ways to manage Connection :[i] DriverManager Connection

[ii] DataSource Connection4. Hibernate supports two ways to manage Transactions :

[i] JDBC Transaction[ii] JTA Transaction (EJB Container or Spring Container)

5. Hibernate provides various Primary Key generation algorithm.6. Hibernate has in-built support for Batch Updates.

7. Hibernate provides various Caching mechanisms.8. Hibernate provides various Object Oriented Query Language (OOQL) :

[a] HQL (Hibernate Query Language)[b] QBC (Query By Criteria)

[c] QBE (Query By Example)9. Hibernate System uses many Persistent best practices and forces the developer to use them

for better performance.

Hibernate Architecture :

Fig : Hibernate Runtime System

Configuration or AnnotationConfiguration :---------------------------------------------------

• There are Classes available in org.hibernate.cfg Package.

• This is the first class that will be instantiated by the Hibernate application.

• We can use Configuration or AnnotationConfiguration class object for 2 tasks :-

(i) calling configure() method or configure(String) method.

(ii) calling buildSessionFactory() method.

• configure() method is responsible for following tasks :-

(i) Reading the data from Hibernate Configuration object.(ii) Reading the data from all the Hibernate mapping documents specified in the

Configuration document.

• buildSessionFactory() method is responsible for creating SessionFactory object.

• Configuration or AnnotationConfiguration object is Single Threaded and Short Lived.

3

Our

ApplicationClient Code

Configuration

SessionFactory

Session

Transaction

ConnectionProvider

Connection

TransactionFactory

JDBC API

JNDI API

JTA API

DBReposity

JNDIReposity

• Once SessionFactory object is created then there is no use with Configuration or

AnnotationConfiguration object.

SessionFactory :

--------------------A SessionFactory is an interface available in org.hibernate package. SessionFactory object is Multi-

Threaded and Long Lived. SessionFactory is clients for connection provider and Transaction Factory.The SessionFactory is created from a Configuration object, and as its name implies it is a factory for

Session objects. The SessionFactory object is used by all the threads of an application. It is athread safe object. The SessionFactory can also provide caching of persistent objects. The main use

of session factory object is to get the session object for the application. SessionFactory hold anoptional (second-level) cache of data that is reusable between transactions, at a process- or

cluster-level. SessionFactorys are immutable. The behaviour of a SessionFactory is controlled byproperties supplied at configuration time. These properties are defined on Environment.

A SessionFactory is usually only built once at startup. SessionFactory should be wrapped in somekind of singleton so that it can be easily accessed in an application code.

Creating object of SessionFactory :SessionFactory sessionFactory = new Configuration().configure().buildSessionfactory();

When we call buildSessionFactory() method on Configuration object then following tasks will

happen :

• Set the defaults to many parameters like BatchSize, FetchSize etc.

• Generates and Caches the SQL Quires required.

• Selects the Connection provider.

• Selects the Transaction Factory.

One SessionFactory object is created per database. Multiple SessionFactory objects (each requiring

a separate Configuration) are created when connecting to multiple databases.

HibernateUtil.java Class for one Database

import org.hibernate.SessionFactory;

import org.hibernate.cfg.Configuration;

public class HibernateUtil {

static SessionFactory factory = null;

static{

Configuration cfg = new Configuration();

cfg = cfg.configure("hibernate.cfg.xml");

factory = cfg.buildSessionFactory();

}

public static SessionFactory getSessionFactory(){

return factory;

}

}

HibernateUtil.java Class for two Databases

import org.hibernate.SessionFactory;

import org.hibernate.cfg.Configuration;

public class HibernateUtil {

static SessionFactory orafactory = null;

static SessionFactory jlcfactory = null;

static{

Configuration cfg = new Configuration();

Configuration cfg1 = cfg.configure("oracle.cfg.xml");

orafactory = cfg1.buildSessionFactory();

Configuration cfg2 = cfg.configure("mysql.cfg.xml");

jlcfactory = cfg2.buildSessionFactory();

}

public static SessionFactory getSessionFactory(int x){

4

if(x==1){

return orafactory;

}else{

return jlcfactory;

}

}

}

Session :-----------

This is an interface available in org.hibernate Package. The representation of single unit of workwith the Java application and the persistence database is done by this object. The wrapping of a

JDBC connection is the emphasized role of a Session interface object. This is the major interfacebetween Java application and Hibernate. This is a runtime interface. The beginning and ending of a

transaction cycle is bounded by the Session interface. The purpose of this interface is to performcreate, read and delete operations for the objects that are mapped with entity classes.

Session session = sessionFactory.openSession();

• Session Object is single Threaded and short Lived.

• Session represents period of time where user can do multiple database operations.

• Holds a mandatory (first-level) cache of persistent objects, used when navigating the object

graph or looking up objects by identifier.

• Session object

(i) use TransactionFactory to get the Transaction.

(ii) get the Connection from Connection Provider.

• It allows us to create query objects to retrieve persistent objects.

Transaction :----------------

When Transaction is started, then following tasks will happened :

• Session Cache will be created.

• Connection will be taken and will be associated with the current session.

While Transaction is commit, following tasks will happen :

• Session will be flushed.

• Session Cache will be destroyed.

• Commit will be issued to database.

• Connection will be realised.

The general flow of Hibernate communication with RDBMS is :-------------------------------------------------------------------------

• The Hibernate configuration is to be loaded and creation of configuration object is done. The

mapping of all hbm files will be performed automatically.

• Creation of session factory from the configuration object.

• Obtain a session from the session factory.

• Creation of HQL Query

• Execution of the query in order to get the list of containing java objects.

DAO + Hibernate (CURD Operation)

------------------------------------------DAO (Data Access Object) is J2EE Design Pattern.

Problem :We can store our Enterprise data in any repository like Flat File, XML Files, LDAP, RDBMS etc.

Note - Commonly used Repository is RDBMS.

When we change the Persistence Storage or Persistence Technology or Framework then we have tochange the Persistence Logic.

5

When We change the Persistence Logic then we may need to change the other Layers of theApplication. This may give maintenance.

Context : When we are interacting with Persistence Storage.

Solution :

Use DAO Design Pattern (J2EE Pattern) 1. Follow the Interface model.

2. Centralize the DAO instance creation in Factory DAO class.3. DAO’s are stateless so create one and only instance for DAO using Singlton Pattern (GOF

Pattern)

Hibernate Util

1. Making one SessionFactory for entire Application per DataBase.2. Reading the data from Hibernate Configuration document and all the mapping document

only once.3. Reducing Code duplication.

Hibernate Template

Reducing the code duplication.

Note : Hibernate uses XML document or properties file to define the object / relational mapping.The ORM File (.hbm file) contains the mapping between the Java object and corresponding

database table.

Hibernate Mapping Type-----------------------------

1. Simple Mapping : When our Persistence Class fields or variables or property of simple type like Primitives, Wrappers, String, Date etc. then use the Simple Mapping.

2. Collection Mapping : When our Persistence class fields or variables or property of

Collection types like List, Set, Map, Array then use Collection Mapping.

3. Inheritance Mapping : When Multiple Persistence Classes are in Inheritance relationship then use Inheritance Mapping.

We can implement Inheritance Mapping in 3 ways :-[a] Table per sub-class Mapping

[b] Table per class Mapping[c] Table per concrete class Mapping

4. Association Mapping : If we want to establish the relationship among different Persistence

Classes, then we have use Association Mapping.Depending on the Cardinality, there are 3 types of Association Mapping :

[a] One-to-One Mapping[b] One-to-Many Mapping

[c] Many-to-Many Mapping

Depending on the Directionality, there are 2 types :1. Uni-Directional Relationship

6

Business

Layer

main()// Client

Code

Integration

LayerInterface

CustomerDAO{addCustomer();

}

class FactoryDAO{

HCD// Siglton class

}

DataBase

J

DB

C

Hibernate

Runtime System

class

HibernateCustomerDAOImpl{

addCustomer(){ // Client Code

}}

------------- Persistence Layer ---------------

EIS Layer

EIS- Enterprise Information System

2. Bi- Directional Relationship

@ Cardinality represents No. of objects participating in relationship on both the sides.@ Directionality represents whether we can access the Data in one direction only or both the

directions.

Inheritance Mapping :--------------------------

Hibernate supports the three basic inheritance mapping strategies:o table per class hierarchy

o table per subclass

o table per concrete class

In addition, Hibernate supports a fourth, slightly different kind of polymorphism:o implicit polymorphism

It is possible to use different mapping strategies for different branches of the same inheritance

hierarchy. You can then make use of implicit polymorphism to achieve polymorphism across thewhole hierarchy. However, Hibernate does not support mixing <subclass>, <joined-

subclass> and<union-subclass> mappings under the same root <class> element. It is possible tomix together the table per hierarchy and table per subclass strategies under the the

same <class> element, by combining the<subclass> and <join> elements (see below for anexample).

It is possible to define subclass, union-subclass, and joined-subclass mappings in separate mappingdocuments directly beneath hibernate-mapping. This allows you to extend a class hierarchy by

adding a new mapping file. You must specify an extends attribute in the subclass mapping, naminga previously mapped superclass. Previously this feature made the ordering of the mapping

documents important. Since Hibernate3, the ordering of mapping files is irrelevant when using theextends keyword. The ordering inside a single mapping file still needs to be defined as superclasses

before subclasses.

<hibernate-mapping> <subclass name="DomesticCat" extends="Cat" discriminator-value="D">

<property name="name" type="string"/> </subclass>

</hibernate-mapping>

Table per class hierarchySuppose we have an interface Payment with the implementors CreditCardPayment, CashPayment,

andChequePayment. The table per hierarchy mapping would display in the following way:

<class name="Payment" table="PAYMENT"> <id name="id" type="long" column="PAYMENT_ID">

<generator class="native"/> </id>

<discriminator column="PAYMENT_TYPE" type="string"/> <property name="amount" column="AMOUNT"/>

... <subclass name="CreditCardPayment" discriminator-value="CREDIT">

<property name="creditCardType" column="CCTYPE"/> ...

</subclass> <subclass name="CashPayment" discriminator-value="CASH">

... </subclass>

<subclass name="ChequePayment" discriminator-value="CHEQUE"> ...

</subclass></class>

7

Exactly one table is required. There is a limitation of this mapping strategy: columns declared by the subclasses, such as CCTYPE, cannot have NOT NULL constraints.

Table per subclass

A table per subclass mapping looks like this:

<class name="Payment" table="PAYMENT"> <id name="id" type="long" column="PAYMENT_ID">

<generator class="native"/> </id>

<property name="amount" column="AMOUNT"/> ...

<joined-subclass name="CreditCardPayment" table="CREDIT_PAYMENT"> <key column="PAYMENT_ID"/>

<property name="creditCardType" column="CCTYPE"/> ...

</joined-subclass> <joined-subclass name="CashPayment" table="CASH_PAYMENT">

<key column="PAYMENT_ID"/> ...

</joined-subclass> <joined-subclass name="ChequePayment" table="CHEQUE_PAYMENT">

<key column="PAYMENT_ID"/> ...

</joined-subclass></class>

Four tables are required. The three subclass tables have primary key associations to the superclass table so the relational model is actually a one-to-one association.

Table per subclass: using a discriminator

Hibernate's implementation of table per subclass does not require a discriminator column. Otherobject/relational mappers use a different implementation of table per subclass that requires a type

discriminator column in the superclass table. The approach taken by Hibernate is much moredifficult to implement, but arguably more correct from a relational point of view. If you want to use

a discriminator column with the table per subclass strategy, you can combine the useof <subclass> and <join>, as follows:

<class name="Payment" table="PAYMENT">

<id name="id" type="long" column="PAYMENT_ID"> <generator class="native"/>

</id> <discriminator column="PAYMENT_TYPE" type="string"/>

<property name="amount" column="AMOUNT"/> ...

<subclass name="CreditCardPayment" discriminator-value="CREDIT"> <join table="CREDIT_PAYMENT">

<key column="PAYMENT_ID"/> <property name="creditCardType" column="CCTYPE"/>

... </join>

</subclass> <subclass name="CashPayment" discriminator-value="CASH">

<join table="CASH_PAYMENT"> <key column="PAYMENT_ID"/>

... </join>

</subclass> <subclass name="ChequePayment" discriminator-value="CHEQUE">

<join table="CHEQUE_PAYMENT" fetch="select"> <key column="PAYMENT_ID"/>

...

8

</join> </subclass>

</class>

The optional fetch="select" declaration tells Hibernate not to fetch the ChequePayment subclass

data using an outer join when querying the superclass.

Mixing table per class hierarchy with table per subclassYou can even mix the table per hierarchy and table per subclass strategies using the following

approach:

<class name="Payment" table="PAYMENT"> <id name="id" type="long" column="PAYMENT_ID">

<generator class="native"/> </id>

<discriminator column="PAYMENT_TYPE" type="string"/> <property name="amount" column="AMOUNT"/>

... <subclass name="CreditCardPayment" discriminator-value="CREDIT">

<join table="CREDIT_PAYMENT"> <property name="creditCardType" column="CCTYPE"/>

... </join>

</subclass> <subclass name="CashPayment" discriminator-value="CASH">

... </subclass>

<subclass name="ChequePayment" discriminator-value="CHEQUE"> ...

</subclass></class>

For any of these mapping strategies, a polymorphic association to the root Payment class is mapped using <many-to-one>.

<many-to-one name="payment" column="PAYMENT_ID" class="Payment"/>

Table per concrete classThere are two ways we can map the table per concrete class strategy. First, you can use<union-

subclass>.

<class name="Payment"> <id name="id" type="long" column="PAYMENT_ID">

<generator class="sequence"/> </id>

<property name="amount" column="AMOUNT"/> ...

<union-subclass name="CreditCardPayment" table="CREDIT_PAYMENT"> <property name="creditCardType" column="CCTYPE"/>

... </union-subclass>

<union-subclass name="CashPayment" table="CASH_PAYMENT"> ...

</union-subclass> <union-subclass name="ChequePayment" table="CHEQUE_PAYMENT">

... </union-subclass>

</class>

Three tables are involved for the subclasses. Each table defines columns for all properties of the class, including inherited properties.

9

The limitation of this approach is that if a property is mapped on the superclass, the column name must be the same on all subclass tables. The identity generator strategy is not allowed in union

subclass inheritance. The primary key seed has to be shared across all unioned subclasses of a hierarchy.

If your superclass is abstract, map it with abstract="true". If it is not abstract, an additional table (it defaults to PAYMENT in the example above), is needed to hold instances of the superclass.

Table per concrete class using implicit polymorphism

An alternative approach is to make use of implicit polymorphism:

<class name="CreditCardPayment" table="CREDIT_PAYMENT"> <id name="id" type="long" column="CREDIT_PAYMENT_ID">

<generator class="native"/> </id>

<property name="amount" column="CREDIT_AMOUNT"/> ...

</class>

<class name="CashPayment" table="CASH_PAYMENT"> <id name="id" type="long" column="CASH_PAYMENT_ID">

<generator class="native"/> </id>

<property name="amount" column="CASH_AMOUNT"/> ...

</class>

<class name="ChequePayment" table="CHEQUE_PAYMENT"> <id name="id" type="long" column="CHEQUE_PAYMENT_ID">

<generator class="native"/> </id>

<property name="amount" column="CHEQUE_AMOUNT"/> ...

</class>

Notice that the Payment interface is not mentioned explicitly. Also notice that properties of Payment are mapped in each of the subclasses. If you want to avoid duplication, consider using

XML entities (for example, [ <!ENTITY allproperties SYSTEM "allproperties.xml"> ] in the DOCTYPE declaration and&allproperties; in the mapping).

The disadvantage of this approach is that Hibernate does not generate SQL UNIONs when performing polymorphic queries.

For this mapping strategy, a polymorphic association to Payment is usually mapped using <any>.

<any name="payment" meta-type="string" id-type="long"> <meta-value value="CREDIT" class="CreditCardPayment"/>

<meta-value value="CASH" class="CashPayment"/> <meta-value value="CHEQUE" class="ChequePayment"/>

<column name="PAYMENT_CLASS"/> <column name="PAYMENT_ID"/>

</any>

Mixing implicit polymorphism with other inheritance mappingsSince the subclasses are each mapped in their own <class> element, and since Payment is just an

interface), each of the subclasses could easily be part of another inheritance hierarchy. You can still use polymorphic queries against the Payment interface.

<class name="CreditCardPayment" table="CREDIT_PAYMENT">

<id name="id" type="long" column="CREDIT_PAYMENT_ID"> <generator class="native"/>

</id> <discriminator column="CREDIT_CARD" type="string"/>

10