Hibernate Interview Question Answer Part 1

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 Address 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 Address 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.
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.
Step 1. In the struts-config.xml add plugin


< plug-in className="org.springframework.web.struts.ContextLoaderPlugIn" >
< set-property property="contextConfigLocation"
value="/WEB-INF/applicationContext.xml"/ >
< /plug-in >


Step 2. In the applicationContext.xml file
Configure datasourse


< bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
< property name="driverClassName" > < value >oracle.jdbc.driver.OracleDriver< / value >
< /property >
< property name="url" >< value >jdbc:oracle:thin:@10.10.01.24:1541:ebizd< / value >
< /property >
< property name="username">sa
< property name="password">
< /bean >


Step 3. Configure SessionFactory


< bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean" >
< property name="dataSource" > < ref local="dataSource"/ > < /property >
< property name="mappingResources" >
< list >
< value >com/test/dbxml/User.hbm.xml< / value >
< /list >
< /property >
< property name="hibernateProperties" >
< props >
< prop key="hibernate.dialect">net.sf.hibernate.dialect.OracleDialect < /prop >
< /props >
< /property >
< /bean >


Step 4. Configure User.hbm.xml


< hibernate-mapping >
< class name="org.test.model.User" table="app_user" >

< id name="id" column="id" >
< generator class="increment"/ >
< / id >
< property name="firstName" column="first_name" not-null="true"/ >
< property name="lastName" column="last_name" not-null="true"/ >

< / class >
< /hibernate-mapping >


Step 5. In the applicationContext.xml ? configure for DAO


< bean id="userDAO" class="org.test.dao.hibernate.UserDAOHibernate" >
< property name="sessionFactory" > < ref local="sessionFactory"/ > < /property >
< /bean >


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); } } 


There are so many

1) Hibernate is data base independent, your code will work for all ORACLE,MySQL ,SQLServer etc. In case of JDBC query must be data base specific

2) As Hibernate is set of Objects,you don?t need to learn SQL language.You can treat TABLE as a Object.Only Java knowledge is need. In case of JDBC you need to learn SQL

3) Don?t need Query tuning in case of Hibernate.If you use Criteria Quires in Hibernate then hibernate automatically tuned your query and return best result with performance. In case of JDBC you need to tune your queries.

4) You will get benefit of Cache. Hibernate support two level of cache.First level and 2nd level.So you can store your data into Cache for better performance. In case of JDBC you need to implement your java cache

5) Hibernate supports Query cache and It will provide the statistics about your query and database status. JDBC Not provides any statistics

6) Development fast in case of Hibernate because you don?t need to write queries

7) No need to create any connection pool in case of Hibernate.You can use c3p0. In case of JDBC you need to write your own connection pool

8) In the xml file you can see all the relations between tables in case of Hibernate. Easy readability

9) You can load your objects on start up using lazy=false in case of Hibernate. JDBC Don?t have such support

10 ) Hibernate Supports automatic versioning of rows but JDBC Not.
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


< class name="beans.Campign" table="CAMPIGN" optimistic-lock="version" >
< id name="campignId" type="long" column="cid" >
< generator class="sequence" >
< param name="sequence">CAMPIGN_ID_SEQ< /param >
< /generator >
< /id >
< version name="versionId" type="long" column="version" / >
< property name="name" column="c_name"/ >
< /class >


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.
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


< class name="beans.Campign" table="CAMPIGN" optimistic-lock="version" >
< id name="campignId" type="long" column="cid" >
< generator class="sequence" >
< param name="sequence" > CAMPIGN_ID_SEQ < /param >
< /generator>
< /id >
< version name="versionId" type="long" column="version"/ >
< property name="name" column="c_name"/ >
< /class >


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.
Lazy setting 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.Exampleslazy=true (default)Address child of User class can be made lazy if it is not required frequently.lazy=false But you may need to load the Author object for Book parent whenever you deal with the book for online bookshop
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


< class name="beans.Campign" table="CAMPIGN" optimistic-lock="version" >
< id name="campignId" type="long" column="cid" >
< generator class="sequence" >
< param name="sequence" > CAMPIGN_ID_SEQ < /param >
< /generator >
< /id >
< version name="versionId" type="long" column="version" / >
< property name="name" column="c_name"/ >
< /class >


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.
saveOrUpdate() does the following:
? if the object is already persistent in this session, do nothing
? if another object associated with the session has the same identifier, throw an exception
? if the object has no identifier property, save() it
? if the object's identifier has the value assigned to a newly instantiated object, save() it
? if the object is versioned (by a < version > or < timestamp>), and the version property value is the same
value assigned to a newly instantiated object, save() it
? otherwise update() the object

merge() is very different: ? if there is a persistent instance with the same identifier currently associated with the session, copy the state of the given object onto the persistent instance
? if there is no persistent instance currently associated with the session, try to load it from the database, or
create a new persistent instance
? the persistent instance is returned
? the given instance does not become associated with the session, it remains detached
load() will throw an unrecoverable exception if there is no matching database row. get() will return null if there is no matching database row.

Cat fritz = (Cat) session.load(Cat.class, "1");

Return the Cat Object with key 1. If there is no Cat Object with key 1 then throw will throw an unrecoverable exception.

If the class is mapped with a proxy, load() just returns an uninitialized proxy and does not actually hit the database until you invoke a method of the proxy. This behaviour is very useful if you wish to create an association to an object without actually loading it from the database. It also allows multiple instances to be loaded as a batch if batchsize is defined for the class mapping.

Cat fritz = (Cat) session.get(Cat.class, "1");

If you are not certain that a matching row exists, you should use the get() method, which hits the database immediately and returns null if there is no matching row.
Equal and Not Equal criteria query- Example


< class name="com.bean.Organization" table="ORGANIZATION" >
< id name="orgId" column="ORG_ID" type="long" >
< generator class="native"/ >
< / id >
< property name="organizationName" column="ORGANISATION_NAME" type="string" length="500"/ >
< property name="town" column="TOWN" type="string" length="200"/ >
< / class >


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();
In the resource bundle file, you can define a template like:


errors.required={0} is required.
ActionErrors errors = new ActionErrors();
errors.add(ActionErrors.GLOBAL_ERROR,
new ActionError("error.custform","First Name"));


Then the Error message is : First Name is required.

Other constructors are

public ActionError(String key, Object value0, Object value1)

. . . public ActionError(String key, Object[] values);
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);
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
SessionFactory.getStatistics()
is give you all the statistics
Criteria Query Two Condition- Example


 < class name="com.bean.Organization" table="ORGANIZATION" >
< id name="orgId" column="ORG_ID" type="long" >
< generator class="native"/ >
< / id >
< property name="organizationName" column="ORGANISATION_NAME" type="string" length="500"/ >
< property name="town" column="TOWN" type="string" length="200"/ >
< property name="statusCode" column="STATUS" type="string" length="1"/ >
< / class >


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();



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.
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()
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.
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.
There are so many

1) Hibernate is data base independent, your code will work for all ORACLE,MySQL ,SQLServer etc. In case of JDBC query must be data base specific.

2) As Hibernate is set of Objects , you don?t need to learn SQL language. You can treat TABLE as a Object . Only Java knowledge is need. In case of JDBC you need to learn SQL.

3) Don?t need Query tuning in case of Hibernate. If you use Criteria Quires in Hibernate then hibernate automatically tuned your query and return best result with performance. In case of JDBC you need to tune your queries.

4) You will get benefit of Cache. Hibernate support two level of cache. First level and 2nd level. So you can store your data into Cache for better performance. In case of JDBC you need to implement your java cache .

5) Hibernate supports Query cache and It will provide the statistics about your query and database status. JDBC Not provides any statistics.

6) Development fast in case of Hibernate because you don?t need to write queries

7) No need to create any connection pool in case of Hibernate. You can use c3p0. In case of JDBC you need to write your own connection pool

8) In the xml file you can see all the relations between tables in case of Hibernate. Easy readability.

9) You can load your objects on start up using lazy=false in case of Hibernate. JDBC Don?t have such support.

10 ) Hibernate Supports automatic versioning of rows but JDBC Not.
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


< class name="beans.Campign" table="CAMPIGN" optimistic-lock="version" >
< id name="campignId" type="long" column="cid" >
< generator class="sequence" >
< param name="sequence" > CAMPIGN_ID_SEQ < /param >


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.
You may express a query in SQL, using createSQLQuery() and let Hibernate take care of the mapping from result sets to objects. Note that you may at any time call session.connection() and use the JDBC Connection directly. If you chose to use the Hibernate API, you must enclose SQL aliases in braces:


List cats = session.createSQLQuery(
"SELECT {cat.*} FROM CAT {cat} WHERE ROWNUM<10",
"cat",
Cat.class
).list();
List cats = session.createSQLQuery(
"SELECT {cat}.ID AS {cat.id}, {cat}.SEX AS {cat.sex}, " +
"{cat}.MATE AS {cat.mate}, {cat}.SUBCLASS AS {cat.class}, ... " +
"FROM CAT {cat} WHERE ROWNUM<10",
"cat",
Cat.class
).list()


SQL queries may contain named and positional parameters, just like Hibernate queries.
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
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:


< sql-query name="selectAllEmployees_SP" callable="true" >
< return alias="emp" class="employee" >
< return-property name="empid" column="EMP_ID" />

< return-property name="name" column="EMP_NAME" />
< return-property name="address" column="EMP_ADDRESS" />
{ ? = call selectAllEmployees() }
< /return >
< /sql-query >


Code:


SQLQuery sq = (SQLQuery) session.getNamedQuery("selectAllEmployees_SP");
List results = sq.list();





< id name="userId" column="USER_ID" type="int" >

< generator class="increment" />


increment generator class automatically generate the primary key for you.
In the resource bundle file, you can define a template like: errors.required={0} is required.


ActionErrors errors = new ActionErrors();
errors.add(ActionErrors.GLOBAL_ERROR,
new ActionError("error.custform","First Name"));

Then the Error message is : First Name is required.

Other constructors are

public ActionError(String key, Object value0, Object value1)

. . . public ActionError(String key, Object[] values);



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);