Wednesday, September 8, 2010

Hibernate Questions

Q. How will you configure Hibernate?

Answer:

The configuration files hibernate.cfg.xml (or hibernate.properties) and mapping files *.hbm.xml are used by the Configuration class to create (i.e. configure and bootstrap hibernate) the SessionFactory, which in turn creates the Session instances. Session instances are the primary interface for the persistence service.

" hibernate.cfg.xml (alternatively can use hibernate.properties): These two files are used to configure the hibernate sevice (connection driver class, connection URL, connection username, connection password, dialect etc). If both files are present in the classpath then hibernate.cfg.xml file overrides the settings found in the hibernate.properties file.

" Mapping files (*.hbm.xml): These files are used to map persistent objects to a relational database. It is the best practice to store each object in an individual mapping file (i.e mapping file per class) because storing large number of persistent classes into one mapping file can be difficult to manage and maintain. The naming convention is to use the same name as the persistent (POJO) class name. For example Account.class will have a mapping file named Account.hbm.xml. Alternatively hibernate annotations can be used as part of your persistent class code instead of the *.hbm.xml files.


Q. What is a SessionFactory? Is it a thread-safe object?

Answer:

SessionFactory is Hibernate s concept of a single datastore and is threadsafe so that many threads can access it concurrently and request for sessions and immutable cache of compiled mappings for a single database. A SessionFactory is usually only built once at startup. SessionFactory should be wrapped in some kind of singleton so that it can be easily accessed in an application code.

SessionFactory sessionFactory = new Configuration().configure().buildSessionfactory();


Q. What is a Session? Can you share a session object between different theads?

Answer:

Session is a light weight and a non-threadsafe object (No, you cannot share it between threads) that represents a single unit-of-work with the database. Sessions are opened by a SessionFactory and then are closed when all work is complete. Session is the primary interface for the persistence service. A session obtains a database connection lazily (i.e. only when required). To avoid creating too many sessions ThreadLocal class can be used as shown below to get the current session no matter how many times you make call to the currentSession() method.

&
public class HibernateUtil {
&
public static final ThreadLocal local = new ThreadLocal();

public static Session currentSession() throws HibernateException {
Session session = (Session) local.get();
//open a new session if this thread has no session
if(session == null) {
session = sessionFactory.openSession();
local.set(session);
}
return session;
}
}

It is also vital that you close your session after your unit of work completes. Note: Keep your Hibernate Session API handy.


Q. What are the benefits of detached objects?

Answer:


Detached objects can be passed across layers all the way up to the presentation layer without having to use any DTOs (Data Transfer Objects). You can later on re-attach the detached objects to another session.

Q. What are the pros and cons of detached objects?

Answer:

Pros:

" When long transactions are required due to user think-time, it is the best practice to break the long transaction up into two or more transactions. You can use detached objects from the first transaction to carry data all the way up to the presentation layer. These detached objects get modified outside a transaction and later on re-attached to a new transaction via another session.


Cons

" In general, working with detached objects is quite cumbersome, and better to not clutter up the session with them if possible. It is better to discard them and re-fetch them on subsequent requests. This approach is not only more portable but also more efficient because - the objects hang around in Hibernate's cache anyway.

" Also from pure rich domain driven design perspective it is recommended to use DTOs (DataTransferObjects) and DOs (DomainObjects) to maintain the separation between Service and UI tiers.


Q. How does Hibernate distinguish between transient (i.e. newly instantiated) and detached objects?

Answer

" Hibernate uses the version property, if there is one.
" If not uses the identifier value. No identifier value means a new object. This does work only for Hibernate managed surrogate keys. Does not work for natural keys and assigned (i.e. not managed by Hibernate) surrogate keys.
" Write your own strategy with Interceptor.isUnsaved().

Q. What is the difference between the session.get() method and the session.load() method?

Both the session.get(..) and session.load() methods create a persistent object by loading the required object from the database. But if there was not such object in the database then the method session.load(..) throws an exception whereas session.get(&) returns null.


Q. What is the difference between the session.update() method and the session.lock() method?

Both of these methods and saveOrUpdate() method are intended for reattaching a detached object. The session.lock() method simply reattaches the object to the session without checking or updating the database on the assumption that the database in sync with the detached object. It is the best practice to use either session.update(..) or session.saveOrUpdate(). Use session.lock() only if you are absolutely sure that the detached object is in sync with your detached object or if it does not matter because you will be overwriting all the columns that would have changed later on within the same transaction.

Note: When you reattach detached objects you need to make sure that the dependent objects are reatched as well.

Q. How would you reatach detached objects to a session when the same object has already been loaded into the session?

You can use the session.merge() method call.


Q. What are the general considerations or best practices for defining your Hibernate persistent classes?


1.You must have a default no-argument constructor for your persistent classes and there should be getXXX() (i.e accessor/getter) and setXXX( i.e. mutator/setter) methods for all your persistable instance variables.

2.You should implement the equals() and hashCode() methods based on your business key and it is important not to use the id field in your equals() and hashCode() definition if the id field is a surrogate key (i.e. Hibernate managed identifier). This is because the Hibernate only generates and sets the field when saving the object.


3. It is recommended to implement the Serializable interface. This is potentially useful if you want to migrate around a multi-processor cluster.

4.The persistent class should not be final because if it is final then lazy loading cannot be used by creating proxy objects.

5.Use XDoclet tags for generating your *.hbm.xml files or Annotations (JDK 1.5 onwards), which are less verbose than *.hbm.xml files.


Difference between session.save() , session.saveOrUpdate() and session.persist()?

session.save() : Save does an insert and will fail if the primary key is already persistent.

session.saveOrUpdate() : saveOrUpdate does a select first to determine if it needs to do an insert or an update.
Insert data if primary key not exist otherwise update data.

session.persist() : Does the same like session.save().
But session.save() return Serializable object but session.persist() return void.
session.save() returns the generated identifier (Serializable object) and session.persist() doesn't.
For Example :
if you do :-
System.out.println(session.save(question));
This will print the generated primary key.
if you do :-
System.out.println(session.persist(question));
Compile time error because session.persist() return void.
Q. What is lazy fetching in Hibernate? With Example .
Lazy fetching decides whether to load child objects while loading the Parent Object.
You need to do this setting respective hibernate mapping file of the parent class.
Lazy = true (means not to load child)
By default the lazy loading of the child objects is true.
This make sure that the child objects are not loaded unless they are explicitly invoked in the application by calling getChild() method on parent.In this case hibernate issues a fresh database call to load the child when getChild() is actully called on the Parent object
.But in some cases you do need to load the child objects when parent is loaded.
Just make the lazy=false and hibernate will load the child when parent is loaded from the database.
Example :
If you have a TABLE ? EMPLOYEE mapped to Employee object and contains set of Address objects.
Parent Class : Employee class
Child class : Address Class
public class Employee {
private Set address = new HashSet(); // contains set of child Address objects
public Set getAddress () {
return address;
}
public void setAddresss(Set address) {
this. address = address;
}
}
In the Employee.hbm.xml file




In the above configuration.
If lazy="false" : - when you load the Employee object that time child object Adress is also loaded and set to setAddresss() method.
If you call employee.getAdress() then loaded data returns.No fresh database call.

If lazy="true" :- This the default configuration. If you don?t mention then hibernate consider lazy=true.
when you load the Employee object that time child object Adress is not loaded. You need extra call to data base to get address objects.
If you call employee.getAdress() then that time database query fires and return results. Fresh database call.

How to Integrate Struts Spring Hibernate ?
Details with code you can deploy in tomcat server and test .

http://www.techfaq360.com/tutorial/spring/struts_spring_hibernate.jsp

Step 1.
In the struts-config.xml add plugin

value="/WEB-INF/applicationContext.xml"/>



Step 2.

In the applicationContext.xml file
Configure datasourse

oracle.jdbc.driver.OracleDriver

jdbc:oracle:thin:@10.10.01.24:1541:ebizd

sa




Step 3.

Configure SessionFactory





com/test/dbxml/User.hbm.xml




net.sf.hibernate.dialect.OracleDialect





Step 4.
Configure User.hbm.xml













Step 5.

In the applicationContext.xml ? configure for DAO





Step 6.

DAO Class
public class UserDAOHibernate extends HibernateDaoSupport implements UserDAO {
private static Log log = LogFactory.getLog(UserDAOHibernate.class);

public List getUsers() {
return getHibernateTemplate().find("from User");
}

public User getUser(Long id) {
return (User) getHibernateTemplate().get(User.class, id);
}

public void saveUser(User user) {
getHibernateTemplate().saveOrUpdate(user);

if (log.isDebugEnabled()) {
log.debug("userId set to: " + user.getId());
}
}

public void removeUser(Long id) {
Object user = getHibernateTemplate().load(User.class, id);
getHibernateTemplate().delete(user);
}
}

How to prevent concurrent update in Hibernate?
version checking used in hibernate when more then one thread trying to access same data.
For example :
User A edit the row of the TABLE for update ( In the User Interface changing data - This is user thinking time)
and in the same time User B edit the same record for update and click the update.
Then User A click the Update and update done. Chnage made by user B is gone.

In hibernate you can perevent slate object updatation using version checking.

Check the version of the row when you are upding the row.
Get the version of the row when you are fetching the row of the TABLE for update.
On the time of updation just fetch the version number and match with your version number ( on the time of fetching).

This way you can prevent slate object updatation.

Steps 1:
Declare a variable "versionId" in your Class with setter and getter.
public class Campign {
private Long versionId;
private Long campignId;
private String name;
public Long getVersionId() {
return versionId;
}
public void setVersionId(Long versionId) {
this.versionId = versionId;
}

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

public Long getCampignId() {
return campignId;
}
private void setCampignId(Long campignId) {
this.campignId = campignId;
}

}

Step 2.
In the .hbm.xml file




CAMPIGN_ID_SEQ









Step 3.
Create a coulmn name "version" in the CAMPIGN table.

Step 4.
In the code
// foo is an instance loaded by a previous Session
session = sf.openSession();
int oldVersion = foo.getVersion();
session.load( foo, foo.getKey() );
if ( oldVersion!=foo.getVersion ) throw new StaleObjectStateException();
foo.setProperty("bar");
session.flush();
session.connection().commit();
session.close();


You can handle StaleObjectStateException() and do what ever you want.
You can display error message.

Hibernate autumatically create/update the version number when you update/insert any row in the table
Filter in Hibernate with Example?
Filter in Hibernate ------
USER ( ID INT, USERNAME VARCHAR, ACTIVATED BOOLEAN) - TABLE
public class User
{
private int id;
private String username;
private boolean activated;
public boolean isActivated()
{
return activated;
}
public void setActivated(boolean activated)
{
this.activated = activated;
}
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public String getUsername()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
}
-----------------------------------------------------------------

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













--------------------------------------------------------------------
Save and Fetch using filter example
User user1 = new User();
user1.setUsername("name1");
user1.setActivated(false);
session.save(user1);
User user2 = new User();
user2.setUsername("name2");
user2.setActivated(true);
session.save(user2);
User user3 = new User();
user3.setUsername("name3");
user3.setActivated(true);
session.save(user3);
User user4 = new User();
user4.setUsername("name4");
user4.setActivated(false);
session.save(user4);
All the four user saved to Data Base User Table.
Now Fetch the User using Filter..
Filter filter = session.enableFilter("activatedFilter");
filter.setParameter("activatedParam",new Boolean(true));
Query query = session.createQuery("from User");
Iterator results = query.iterate();
while (results.hasNext())
{
User user = (User) results.next();
System.out.print(user.getUsername() + " is ");
}
Guess the Result :
name2 name3

Because Filer is filtering ( only true value) data before query execute.
Difference between list() and iterate() i9n Hibernate?
If instances are already be in the session or second-level cache iterate() will give better performance.
If they are not already cached, iterate() will be slower
than list() and might require many database hits for a simple query.
Deleting persistent objects
Session.delete() will remove an object's state from the database. Of course, your application might still hold
a reference to a deleted object. It's best to think of delete() as making a persistent instance transient.
sess.delete(cat);
SQL statements execution order.
1. all entity insertions, in the same order the corresponding objects were saved using Session.save()
2. all entity updates
3. all collection deletions
4. all collection element deletions, updates and insertions
5. all collection insertions
6. all entity deletions, in the same order the corresponding objects were deleted using Session.delete()

Modifying persistent objects?
DomesticCat cat = (DomesticCat) sess.load( Cat.class, new Long(69) );
cat.setName("PK");
sess.flush(); // changes to cat are automatically detected and persisted To Data Base.

No need any session.update() call
Criteria Query Two Condition
Criteria Query Two Condition- Example








List of organisation where town equals to pune and status = "A".

List organizationList = session.createCriteria(Organization.class)
.add(Restrictions.eq("town","pune"))
.add(Restrictions.eq("statusCode","A"))
.list();
Equal and Not Equal criteria query.
Equal and Not Equal criteria query- Example







List of organisation where town equals to pune.
List organizationList = session.createCriteria(Organization.class).add(Restrictions.eq("town","pune")).list();
List of organisation where town not equals pune.
List organizationList = session.createCriteria(Organization.class).add(Restrictions.ne("town","pune")).list();
Cascade Save or Update in Hibernate ?
Cascade Save or Update - In one to Many- EXAMPLE
PROCESS_TYPE_LOV (PROCESS_TYPE_ID number, PROCESS_TYPE_NAME varchar) - TABLE
PROCESS (PROCESS_ID number,PROCESS_NAME varchar,PROCESS_TYPE_ID number)- TABLE

public class ProcessTypeBean {
private Long processTypeId;
private String processTypeName;

/**
* @return Returns the processTypeId.
*/
public Long getProcessTypeId() {
return processTypeId;
}
/**
* @param processTypeId The processTypeId to set.
*/
public void setProcessTypeId(Long processTypeId) {
this.processTypeId = processTypeId;
}
/**
* @return Returns the processTypeName.
*/
public String getProcessTypeName() {
return processTypeName;
}
/**
* @param processTypeName The processTypeName to set.
*/
public void setProcessTypeName(String processTypeName) {
this.processTypeName = processTypeName;
}
}

public class ProcessBean {
private Long processId;
private String processName = "";
private ProcessTypeBean processType;
public Long getProcessId() {
return processId;
}
/**
* @param processId The processId to set.
*/
public void setProcessId(Long processId) {
this.processId = processId;
}
/**
* @return Returns the processName.
*/
public String getProcessName() {
return processName;
}
/**
* @param processName The processName to set.
*/
public void setProcessName(String processName) {
this.processName = processName;
}
/**
* @return Returns the processType.
*/
public ProcessTypeBean getProcessType() {
return processType;
}
/**
* @param processType The processType to set.
*/
public void setProcessType(ProcessTypeBean processType) {
this.processType = processType;
}
}

table="PROCESS">

length="50" />



table="PROCESS_TYPE_LOV">

type="string" length="50" />

---------------------------------------------------------------------------------
Save Example Code -
ProcessTypeBean pstype = new ProcessTypeBean();
pstype.setProcessTypeName("Java Process");
ProcessBean process = new ProcessBean();
process.setProcessName("Production")
ProcessBean.setProcessType(pstype);

// session.save(pstype); -- This save not required because of in the mapping file cascade="save-update"
session.save(process); - This will insert both ProcessBean and ProcessTypeBean;
One To Many Bi-directional Relation in Hibernate?
Bi-DireCtional One to Many Relation- EXAMPLE
PROCESS_TYPE_LOV (PROCESS_TYPE_ID number, PROCESS_TYPE_NAME varchar) - TABLE
PROCESS (PROCESS_ID number,PROCESS_NAME varchar,PROCESS_TYPE_ID number)- TABLE

public class ProcessTypeBean {

private Long processTypeId;
private String processTypeName;
private List processes = null;

/**
* @return Returns the processes.
*/
public List getProcesses() {
return processes;
}
/**
* @param processes The processes to set.
*/
public void setProcesses(List processes) {
this.processes = processes;
}

/**
* @return Returns the processTypeId.
*/
public Long getProcessTypeId() {
return processTypeId;
}
/**
* @param processTypeId The processTypeId to set.
*/
public void setProcessTypeId(Long processTypeId) {
this.processTypeId = processTypeId;
}
/**
* @return Returns the processTypeName.
*/
public String getProcessTypeName() {
return processTypeName;
}
/**
* @param processTypeName The processTypeName to set.
*/
public void setProcessTypeName(String processTypeName) {
this.processTypeName = processTypeName;
}

}

public class ProcessBean {

private Long processId;
private String processName = "";
private ProcessTypeBean processType;

public Long getProcessId() {
return processId;
}
/**
* @param processId The processId to set.
*/
public void setProcessId(Long processId) {
this.processId = processId;
}
/**
* @return Returns the processName.
*/
public String getProcessName() {
return processName;
}
/**
* @param processName The processName to set.
*/
public void setProcessName(String processName) {
this.processName = processName;
}
/**
* @return Returns the processType.
*/
public ProcessTypeBean getProcessType() {
return processType;
}
/**
* @param processType The processType to set.
*/
public void setProcessType(ProcessTypeBean processType) {
this.processType = processType;
}
}

table="PROCESS">

length="50" />




table="PROCESS_TYPE_LOV">

type="string" length="50" />



class="com.bean.ProcessBean" />


One To Many Mapping Using List ?
WRITER (ID INT,NAME VARCHAR) - TABLE
STORY (ID INT,INFO VARCHAR,PARENT_ID INT) - TABLE
One writer can have multiple stories..
-------------------------------------------------------------
Mapping File...

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













table="story">






-------------------------------------------------------
public class Writer {
private int id;
private String name;
private List stories;


public void setId(int i) {
id = i;
}

public int getId() {
return id;
}

public void setName(String n) {
name = n;
}

public String getName() {
return name;
}

public void setStories(List l) {
stories = l;
}

public List getStories() {
return stories;
}
}

---------------------------------------------------
public class Story {
private int id;
private String info;

public Story(){
}

public Story(String info) {
this.info = info;
}

public void setId(int i) {
id = i;
}

public int getId() {
return id;
}

public void setInfo(String n) {
info = n;
}

public String getInfo() {
return info;
}
}
----------------------------------------------------

Save Example ..
Writer wr = new Writer();
wr.setName("Das");

ArrayList list = new ArrayList();
list.add(new Story("Story Name 1"));
list.add(new Story("Story Name 2"));
wr.setStories(list);

Transaction transaction = null;

try {
transaction = session.beginTransaction();
session.save(sp);
transaction.commit();
} catch (Exception e) {
if (transaction != null) {
transaction.rollback();
throw e;
}
} finally {
session.close();
}
Many To Many Relation In Hibernate ?
Best Example..for Many to Many in Hibernate ..
EVENTS ( uid int, name VARCHAR) Table
SPEAKERS ( uid int, firstName VARCHAR) Table
EVENT_SPEAKERS (elt int, event_id int, speaker_id int) Table
-----------------------------------------------------------
import java.util.Set;
import java.util.HashSet;

public class Speaker{

private Long id;
private String firstName;
private Set events;

public Long getId() {
return id;
}

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

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public Set getEvents() {
return this.events;
}

public void setEvents(Set events) {
this.events = events;
}

private void addEvent(Event event) {
if (events == null) {
events = new HashSet();
}
events.add(event);
}
}
--------------------------------------------------------
import java.util.Date;
import java.util.Set;

public class Event{

private Long id;
private String name;
private Set speakers;

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

public Long getId() {
return id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public void setSpeakers(Set speakers) {
this.speakers = speakers;
}

public Set getSpeakers() {
return speakers;
}

}
--------------------------------------------------------------
Event.hbm.xml

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













------------------------------------------------------------------
Speaker.hbm.xml


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













----------------------------------------------------------------------
Save and Fetch Example
Event event = new Event();
event.setName("Inverse test");
event.setSpeakers(new HashSet());
event.getSpeakers().add(new Speaker("Ram", event));
event.getSpeakers().add(new SpeakerManyToMany("Syam", event));
event.getSpeakers().add(new SpeakerManyToMany("Jadu", event));
session.save(event); /// Save All the Data

event = (Event) session.load(Event.class, event.getId());
Set speakers = event.getSpeakers();

for (Iterator i = speakers.iterator(); i.hasNext();) {
Speaker speaker = (Speaker) i.next();
System.out.println(speaker.getFirstName());
System.out.println(speaker.getId());
}

How to set 2nd level cache in hibernate with EHCache?
When you are creating SessionFactory just add the below steps

String ecache = appHome+File.separatorChar+"ehcache.xml";
try {
CacheManager.create(ecache);
} catch (CacheException e) {
// logger.logError(e);
}*/

Then
sessionFactory = configuration.buildSessionFactory();

ECache.xml is like


maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
/>

maxElementsInMemory="300"
eternal="false"
overflowToDisk="false"
/>


ApplicationBean will be avilable in 2nd level cache
How to get JDBC connections in hibernate?
User Session.connection() method to get JDBC Connection.
How will you configure Hibernate?
Step 1> Put Hibernate properties in the classpath.
Step 2> Put .hbm.xml in class path ?
Code is Here to create session ...

package com.dao;
import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;
import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

/**
*
* @author Satya Das
*/
public class HibernateUtil {
protected static final Logger logger=Logger.getLogger(HibernateUtil.class);
public static String appHome = "No";
private static SessionFactory sessionFactory;
private static final ThreadLocal threadSession = new ThreadLocal();
private static final ThreadLocal threadTransaction = new ThreadLocal();
/**
* Initialize Hibernate Configuration
*/
public static void initMonitor(){
logger.info("Hibernate configure");
try {
logger.info("appHome"+appHome);
String path_properties = appHome+File.separatorChar+"hibernate.properties";
String path_mapping = appHome+File.separatorChar+"mapping_classes.mysql.hbm.xml";
//String ecache = appHome+File.separatorChar+"ehcache.xml";

Properties propHibernate = new Properties();
propHibernate.load(new FileInputStream(path_properties));

Configuration configuration = new Configuration();
configuration.addFile(path_mapping);
configuration.setProperties(propHibernate);

/* try {
CacheManager.create(ecache);
} catch (CacheException e) {
// logger.logError(e);
}*/

sessionFactory = configuration.buildSessionFactory();
} catch (Throwable ex) {
logger.error("Exception in initMonitor",ex);
throw new ExceptionInInitializerError(ex);
}
}
/**
* @return a Session Factory Object
*/
public static SessionFactory getSessionFactory() {
logger.info("Inside getSessionFactory method");
try {
if (sessionFactory == null) {
initMonitor();
}else {

//sessionFactory.getStatistics().logSummary();
}
} catch (Exception e) {
logger.error("Exception in getSessionFactory",e);
}
return sessionFactory;
}

/**
* @return Session . Start a Session
*/
public static Session getSession() {
Session s = (Session) threadSession.get();
logger.debug("session"+s);
if (s == null) {
s = getSessionFactory().openSession();
threadSession.set(s);
logger.debug("session 1 $"+s);
}
return s;
}

/**
* Close Session
*/
public static void closeSession(){

Session s = (Session) threadSession.get();
threadSession.set(null);
if (s != null && s.isOpen()) {
s.flush();
s.close();
}
}

/**
* Start a new database transaction.
*/
public static void beginTransaction(){
Transaction tx = null;
if (tx == null) {
tx = getSession().beginTransaction();
threadTransaction.set(tx);
}
}

/**
* Commit the database transaction.
*/
public static void commitTransaction(){
Transaction tx = (Transaction) threadTransaction.get();
try {
if ( tx != null ) {
tx.commit();
}
threadTransaction.set(null);
} catch (HibernateException ex) {
rollbackTransaction();
throw ex;
}
}

/**
* Rollback the database transaction.
*/
public static void rollbackTransaction(){

Transaction tx = (Transaction) threadTransaction.get();
try {
threadTransaction.set(null);
if ( tx != null && !tx.wasCommitted() && !tx.wasRolledBack() ) {
tx.rollback();
}
} finally {
closeSession();
}
}
}
What are the Instance states in Hibernate?
transient
The instance is not, and has never been associated with any persistence context. It has no persistent identity
(primary key value).
persistent
The instance is currently associated with a persistence context. It has a persistent identity (primary key
value) and, perhaps, a corresponding row in the database. For a particular persistence context, Hibernate
guarantees that persistent identity is equivalent to Java identity (in-memory location of the object).
detached
The instance was once associated with a persistence context, but that context was closed, or the instance
was serialized to another process. It has a persistent identity and, perhaps, a corrsponding row in the database.
For detached instances, Hibernate makes no guarantees about the relationship between persistent
identity and Java identity.
What are the core components in Hibernate ?
SessionFactory (org.hibernate.SessionFactory)
A threadsafe (immutable) cache of compiled mappings for a single database. A factory for Session and a
client of ConnectionProvider. Might hold an optional (second-level) cache of data that is reusable
between transactions, at a process- or cluster-level.
Session (org.hibernate.Session)
A single-threaded, short-lived object representing a conversation between the application and the persistent
store. Wraps a JDBC connection. Factory for Transaction. Holds a mandatory (first-level) cache of persistent
objects, used when navigating the object graph or looking up objects by identifier.
Persistent objects and collections
Short-lived, single threaded objects containing persistent state and business function. These might be ordinary
JavaBeans/POJOs, the only special thing about them is that they are currently associated with (exactly
one) Session. As soon as the Session is closed, they will be detached and free to use in any application
layer (e.g. directly as data transfer objects to and from presentation).
Transient and detached objects and collections
Instances of persistent classes that are not currently associated with a Session. They may have been instantiated
by the application and not (yet) persisted or they may have been instantiated by a closed Session.
Transaction (org.hibernate.Transaction)
(Optional) A single-threaded, short-lived object used by the application to specify atomic units of work.
Abstracts application from underlying JDBC, JTA or CORBA transaction. A Session might span several
Transactions in some cases. However, transaction demarcation, either using the underlying API or Transaction,
is never optional!
Architecture
Hibernate 3.0.2 9
ConnectionProvider (org.hibernate.connection.ConnectionProvider)
(Optional) A factory for (and pool of) JDBC connections. Abstracts application from underlying Datasource
or DriverManager. Not exposed to application, but can be extended/implemented by the developer.
TransactionFactory (org.hibernate.TransactionFactory)
(Optional) A factory for Transaction instances. Not exposed to the application, but can be extended/
implemented by the developer.
Extension Interfaces
Hibernate offers many optional extension interfaces you can implement to customize the behavior of your
persistence layer. See the API documentation for details.
What is a Hibernate Session? Can you share a session object between different theads?
Session is a light weight and a non-threadsafe object (No, you cannot share it between threads) that represents a single unit-of-work with the database. Sessions are opened by a SessionFactory and then are closed when all work is complete. Session is the primary interface for the persistence service. A session obtains a database connection lazily (i.e. only when required). To avoid creating too many sessions ThreadLocal class can be used as shown below to get the current session no matter how many times you make call to the currentSession() method.

?
public class HibernateUtil {
?
public static final ThreadLocal local = new ThreadLocal();

public static Session currentSession() throws HibernateException {
Session session = (Session) local.get();
//open a new session if this thread has no session
if(session == null) {
session = sessionFactory.openSession();
local.set(session);
}
return session;
}
}
addScalar() method in hibernate...
Double max = (Double) sess.createSQLQuery("select max(cat.weight) as maxWeight from cats cat")
.addScalar("maxWeight", Hibernate.DOUBLE);
.uniqueResult();

addScalar() method confim that maxWeight is always double type.

This way you don't need to check for it is double or not.
Difference between session.save() and session.saveOrUpdate()?
session.save() - Insert data into the table
session.saveOrUpdate()- Insert data if primary key not exist otherwise update
How are joins handled using Hinernate.
Best is use Criteria query
Example -
You have parent class
public class Organization {
private long orgId;
private List messages;
}
Child class
public class Message {
private long messageId;
private Organization organization;
}

.hbm.xml file




class="com.bean.Message" />










Get all the messages from message table where organisation id =

Criteria query is :
session.createCriteria(Message.class).createAlias("organization","org").
add(Restrictions.eq("org.orgId",new Long(orgId))).add(Restrictions.in("statusCode",status)).list();

you can get all the details in hibernate website.
http://www.hibernate.org/hib_docs/reference/en/html/associations.html
What is Hibernate proxy?
By default Hibernate creates a proxy for each of the class you map in mapping file. This class contain the code to invoke JDBC. This class is created by hibernate using CGLIB.

Proxies are created dynamically by subclassing your object at runtime. The subclass has all the methods of the parent, and when any of the methods are accessed, the proxy loads up the real object from the DB and calls the method for you. Very nice in simple cases with no object hierarchy. Typecasting and instanceof work perfectly on the proxy in this case since it is a direct subclass.
how to create primary key using hibernate?




increment generator class automatically generate the primary key for you.
How to Execute Stored procedure in Hibernate ?
Option 1:
Connection con = null;


try {
con = session.connection();

CallableStatement st = con
.prepareCall("{call your_sp(?,?)}");
st.registerOutParameter(2, Types.INTEGER);
st.setString(1, "some_Seq");

st.executeUpdate();

Option 2:






{ ? = call selectAllEmployees() }



code :

SQLQuery sq = (SQLQuery) session.getNamedQuery("selectAllEmployees_SP");

List results = sq.list();



1) Adv/Disadvantages of Hibernate:

a) Object - Relational mapping

b) The developer doesn't have to take into account the type of database he is coding for. The type of database can be changed by changing the dialect line in the configuration file.

c) Hibernate has caching.

d) Need to write less complex queries.

e) One has the choice as to how he wants the related objects of the object he wants to be loaded. (Fetching and join strategy)

f) Connection Pooling can be done by editing a few lines in the hibernate-cfg.xml file ..

c3p0 :- connection pool built in with Hibernate


hibernate.connection.driver_class=com.mysql.jdbc.Driver
hibernate.connection.url=jdbc:mysql://localhost/hibernate
hibernate.connection.username=root
hibernate.connection.password=
hibernate.dialect=net.sf.hibernate.dialect.MySQLDialect
hibernate.show_sql=false

hibernate.c3p0.max_size=1
hibernate.c3p0.min_size=0
hibernate.c3p0.timeout=5000
hibernate.c3p0.max_statements=100
hibernate.c3p0.idle_test_period=300
hibernate.c3p0.acquire_increment=2
Disadvantages:

slower in processing the queries than if the queries are used directly
adding the xml would cause portability problems

2) Explain Session Factory?

SessionFactory is Hibernate’s concept of a single datastore and is threadsafe so that many threads can access it concurrently and request for sessions and immutable cache of compiled mappings for a single database. A SessionFactory is usually only built once at startup. SessionFactory should be wrapped in some kind of singleton so that it can be easily accessed in an application code.

SessionFactory sessionFactory = new Configuration().configure().buildSessionfactory

3) Explain different type of fetch statements?

Fetching strategy is used by hibernate to retrieve associated objects if the Hibernate needs to go through to the association.
There are 4 types of fetching strategies:

fetch = join

Using the same 'select' statement the Hibernate will fetch the associated instance/ collection using outer join.

fetch = select

This is the default option. If there are 'n' associated objects to the one you requested then there would be 'n+1' select statements executed. If the lazy=true then these would executed only when the association is required.

fetch = subselect

A second select statement would be used to get all the related objects. If the lazy=true then this second select statement would be executed only when the association is called.

fetch=batch

It is an optimization strategy for fetch=select , where in using a list of primary or foreign keys one would pull out all instances/collection in a single select.

4) Explain lazy loading?

5) Explain object states?

Transient

Persistent

Detached:

Detached objects have a representation in database but changes done to the object won't be reflected to the database. A detached objects can be created by closing the session or by using the evict method of the session on the object. In order to reflect the changes in the object to the database the load,refresh,merge,update or save method on the object in any session.

6) Performance metrics in Hibernate?

sessionFactory.getStatistics

7) What is the difference between the session.get() method and the session.load() method?

Both the session.get(..) and session.load() methods create a persistent object by loading the required object from the database. But if there was not such object in the database then the method session.load(..) throws an exception whereas session.get(…) returns null


8) Explain caching in Hibernate


Hibernate uses two different caches for objects: first-level cache and second-level cache. First-level cache is associated with the Session object, while second-level cache is associated with the Session Factory object. By default, Hibernate uses first-level cache on a per-transaction basis. Hibernate uses this cache mainly to reduce the number of SQL queries it needs to generate within a given transaction. For example, if an object is modified several times within the same transaction, Hibernate will generate only one SQL UPDATE statement at the end of the transaction, containing all the modifications. This article focuses on second-level cache. To reduce database traffic, second-level cache keeps loaded objects at the Session Factory level between transactions. These objects are available to the whole application, not just to the user running the query. This way, each time a query returns an object that is already loaded in the cache, one or more database transactions potentially are avoided.
In addition, you can use a query-level cache if you need to cache actual query results, rather than just persistent objects.


Each cache provides different capacities in terms of performance, memory use, and configuration possibilities:
EHCache is a fast, lightweight, and easy-to-use in-process cache. It supports read-only and read/write caching, and memory- and disk-based caching. However, it does not support clustering.
OSCache is another open-source caching solution. It is part of a larger package, which also provides caching functionalities for JSP pages or arbitrary objects. It is a powerful and flexible package, which, like EHCache, supports read-only and read/write caching, and memory- and disk-based caching. It also provides basic support for clustering via either JavaGroups or JMS.
SwarmCache is a simple cluster-based caching solution based on JavaGroups. It supports read-only or nonstrict read/write caching (the next section explains this term). This type of cache is appropriate for applications that typically have many more read operations than write operations.
JBoss TreeCache is a powerful replicated (synchronous or asynchronous) and transactional cache. Use this solution if you really need a true transaction-capable caching architecture.
Another cache implementation worth mentioning is the commercial Tangosol Coherence cache.

Caching Strategies
Once you have chosen your cache implementation, you need to specify your access strategies. The following four caching strategies are available:
Read-only: This strategy is useful for data that is read frequently but never updated. This is by far the simplest and best-performing cache strategy.
Read/write: Read/write caches may be appropriate if your data needs to be updated. They carry more overhead than read-only caches. In non-JTA environments, each transaction should be completed when Session.close() or Session.disconnect() is called.
Nonstrict read/write: This strategy does not guarantee that two transactions won't simultaneously modify the same data. Therefore, it may be most appropriate for data that is read often but only occasionally modified.
Transactional: This is a fully transactional cache that may be used only in a JTA environment.

9) Proxy pattern in Hibernate:

When an object contains another object and the loading is lazy then when the main object is created then it contains only a refernce to the object it contains. This reference is the proxy of the object it contains and this pattern is called proxy patters.

10) Interfaces in Hibernate:

Configuration,Session,Transaction and SessionFactory
11) Light weight ,Medium Weight and Heavy Weight mapping:

There are four levels of Hibernate Quality:

Pure: Stored Procedures

Light: JDBC

Medium:

Heavy:composition,inheritance, polymorphism, persistence by reachability



12) Difference between Hibernate and Ibatis:

In Ibatis Results of the SQL queries are mapped to the Objects where as in Hibernate the table is mapped to the object. Ibatis would be faster as it making use of the queries directly and is useful when you personally don't have much knowledge about the database.

13) What is NHibernate?

NHibernate is an Object Relational Mapping (ORM) solution for .Net.

14) Integrating Hibernate and Spring

1) Configure the SessionFactory in the 'spring.xml'


abcde/a.hbm.xml
abcde/b.hbm.xml


p:dataSource-ref="data.source.DataSource"
p:mappingResources-ref="abc.MappingResources"
p:hibernateProperties-ref="abc.HibernateProperties">



javax.transaction.TransactionManager





2) Configure the DataSource in the 'spring.xml'

class="org.springframework.jdbc.datasource.DriverManagerDataSource">


org.hsqldb.jdbcDriver


jdbc:hsqldb:mem:widgets


sa



3) Extend your DAO Implementation from HibernateDaoSupport

No comments: