3.What do you mean by Named – SQL query?
Named SQL queries are defined in the mapping xml document and called wherever required.
Example:
<sql-query name = "empdetails">
<return alias="emp" class="com.test.Employee"/>
SELECT emp.EMP_ID AS {emp.empid},
emp.EMP_ADDRESS AS {emp.address},
emp.EMP_NAME AS {emp.name}
FROM Employee EMP WHERE emp.NAME LIKE :name
</sql-query>
Invoke Named Query :
List people = session.getNamedQuery("empdetails")
.setString("TomBrady", name)
.setMaxResults(50)
.list();
Named queries are SQL queries which are defined in mapping document using <sql-query> tag and called using Session.getNamedQuery() method. Named query allows you to refer a particular query by the name you provided, by the way you can define named query in hibernate either by using annotations or xml mapping file, as I said above. @NameQuery is used to define single named query and @NameQueries is used to define multiple named query in hibernate.
4.What is difference between get and load method in Hibernate?
1. session.load()
·
It will always return
a “proxy” (Hibernate term) without hitting the database. In Hibernate,
proxy is an object with the given identifier value, its properties are not
initialized yet, it just look like a temporary fake object.
·
If no row found , it
will throws an ObjectNotFoundException.
2. session.get()
·
It always hit
the database and return the real object, an object that represent the
database row, not proxy.
·
If no row found , it
return null.
It’s about performance
Hibernate create
anything for some reasons, when you do the association, it’s normal to obtain
retrieve an object (persistent instance) from database and assign it as a
reference to another object, just to maintain the relationship. Let’s go
through some examples to understand in what situation you should use session.load().
1. session.get()
For example, in a
Stock application , Stock and StockTransactions should have a “one-to-many”
relationship, when you want to save a stock transaction, it’s common to declared
something like below
Stock stock = (Stock)session.get(Stock.class,
new Integer(2));
StockTransaction stockTransactions = new StockTransaction();
//set
stockTransactions detail
stockTransactions.setStock(stock);
session.save(stockTransactions);
Output
Hibernate:
select ... from
mkyong.stock stock0_
where
stock0_.STOCK_ID=?
Hibernate:
insert into
mkyong.stock_transaction (...)
values (?, ?, ?, ?, ?,
?)
In session.get(), Hibernate
will hit the database to retrieve the Stock object and put it as a reference to
StockTransaction. However, this save process is extremely high demand, there
may be thousand or million transactions per hour, do you think is this
necessary to hit the database to retrieve the Stock object everything save a
stock transaction record? After all you just need the Stock’s Id as a reference
to StockTransaction.
2. session.load()
In above scenario, session.load() will
be your good solution, let’s see the example,
Stock stock = (Stock)session.load(Stock.class,
new Integer(2));
StockTransaction stockTransactions = new StockTransaction();
//set
stockTransactions detail
stockTransactions.setStock(stock);
session.save(stockTransactions);
Output
Hibernate:
insert into
mkyong.stock_transaction (...)
values (?, ?, ?, ?, ?,
?)
In session.load(),
Hibernate will not hit the database (no select statement in output) to retrieve
the Stock object, it will return a Stock proxy object – a fake object with
given identify value. In this scenario, a proxy object is enough for to save a
stock transaction record.
Exception
In exception case, see
the examples
session.load()
Stock stock = (Stock)session.load(Stock.class, new Integer(100));
//proxy
//initialize proxy, no
row for id 100, throw ObjectNotFoundException
System.out.println(stock.getStockCode());
It will always return
a proxy object with the given identity value, even the identity value is not
exists in database. However, when you try to initialize a proxy by retrieve
it’s properties from database, it will hit the database with select statement. If
no row is found, a ObjectNotFoundException will throw.
org.hibernate.ObjectNotFoundException: No row with the given
identifier exists:
[com.mkyong.common.Stock#100]
session.get()
//return null if not found
Stock stock = (Stock)session.get(Stock.class, new Integer(100));
System.out.println(stock.getStockCode()); //java.lang.NullPointerException
It will always return
null , if the identity value is not found in database.
5.What is hibernate caching and different types of it?
Fist level cache in hibernate is enabled by default and you do not need to do anything to get this functionality working. In fact, you can not disable it even forcefully.
Its easy to understand the first level cache if we understand the fact that it is associated with Session object. As we know session object is created on demand from session factory and it is lost, once the session is closed. Similarly, first level cache associated with session object is available only till session object is live. It is available to session object only and is not accessible to any other session object in any other part of application.
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Session sessionTemp = HibernateUtil.getSessionFactory().openSession();
sessionTemp.beginTransaction();
try
{
DepartmentEntity department = (DepartmentEntity) session.load(DepartmentEntity.
class
,
new
Integer(
1
));
System.out.println(department.getName());
department = (DepartmentEntity) session.load(DepartmentEntity.
class
,
new
Integer(
1
));
System.out.println(department.getName());
department = (DepartmentEntity) sessionTemp.load(DepartmentEntity.
class
,
new
Integer(
1
));
System.out.println(department.getName());
}
finally
{
session.getTransaction().commit();
HibernateUtil.shutdown();
sessionTemp.getTransaction().commit();
HibernateUtil.shutdown();
}
Output:
Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
Human Resource
Human Resource
Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
Human Resource
Above statement means, second level cache is created in session factory scope and is available to be used in all sessions which are created using that particular session factory.
It also means that once session factory is closed, all cache associated with it die and cache manager also closed down.
Configuring EhCache
To configure ehcache, you need to do two steps:
- configure Hibernate for second level caching
- specify the second level cache provider
Hibernate 3.3 and above
1
2
|
< property key = "hibernate.cache.use_second_level_cache" >true</ property >
< property name = "hibernate.cache.region.factory_class" >net.sf.ehcache.hibernate.EhCacheRegionFactory</ property >
|
Hibernate 3.2 and below
1
2
|
< property key = "hibernate.cache.use_second_level_cache" >true</ property >
< property name = "hibernate.cache.region.provider_class" >net.sf.ehcache.hibernate.EhCacheProvider</ property >
|
Configuring entity objects
This may done in two ways.
1) If you are using hbm.xml files then use below configuration:
1
2
3
|
< class name = "com.application.entity.DepartmentEntity" table = "..." >
< cache usage = "read-write" />
</ class >
|
2) Otherwise, if you are using annotations, use these annotations:
1
2
3
4
5
6
7
|
@Entity
@Cache (usage=CacheConcurrencyStrategy.READ_ONLY,
region= "department" )
public class DepartmentEntity implements Serializable
{
}
|
For both options, caching strategy can be of following types:
- none : No caching will happen.
- read-only : If your application needs to read, but not modify, instances of a persistent class, a read-only cache can be used.
- read-write : If the application needs to update data, a read-write cache might be appropriate.
- nonstrict-read-write : If the application only occasionally needs to update data (i.e. if it is extremely unlikely that two transactions would try to update the same item simultaneously), and strict transaction isolation is not required, a nonstrict-read-write cache might be appropriate.
- transactional : The transactional cache strategy provides support for fully transactional cache providers such as JBoss TreeCache. Such a cache can only be used in a JTA environment and you must specify hibernate.transaction.manager_lookup_class.
5.What is difference between Update() and merge() method in Hibernate?
Update():- if you are sure that the session does not contains an already persistent instance with the same identifier then use update to save the data in hibernate
Merge():-if you want to save your modificatiions at any time with out knowing abot the state of an session then use merge() in hibernate.
SessionFactory sf = ctx.getBean("hibernateSessionFactory",SessionFactory.class);
Session session = sf.openSession();
Transaction t = session.beginTransaction();
try {
Session s2 = sf.openSession();
Organization org = (Organization)s2.get(Organization.class,100624l);//1
org.setOrgName("org");
s2.close();//2
Organization org1 = (Organization)session.get(Organization.class,100624l);//3
org.setOrgName("testOrg");
org1.setOrgName("org");//a
session.merge(org);//4
System.out.println(org == org1);//b
t.commit();
} catch (HibernateException e) {
t.rollback();
throw e;
}finally{
session.close();
}
- 1st instance is loaded and made persistent.
- The instance is detached.
- Another instance is loaded
- At the point of executing this operation, there are 2 instances of the same object in the session(org and org1) – org is detached and org1 is persistent If we do an update() or saveOrUpdate() there, we get the below exception:
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.spring.model.Organization#100624]
a. We do a merge here which:
I. Merges the state of the detached object + persistent object.
II. In case of conflict, the object which is merged wins, like in this case, the value saved will be : testOrg
III. Had we merged on org1, we would have got org.
b. This will always return false, meaning post merge, org was still in DETACHED state
I hope the diff. is clear now.
Summary : saveOrUpdate() or update() will throw an exception if there are 2 instances of the same object in the session(one detached and one persistent)
merge() will not throw the exception, but will save the object while merging the changes.
6.What is difference between update() and saveorUpdate() method in Hibernate?
save
Save method stores an object into the database. That means it insert an entry if the identifier doesn’t exist, else it will throw error. If the primary key already present in the table, it cannot be inserted.
update
Update method in the hibernate is used for updating the object using identifier. If the identifier is missing or doesn’t exist, it will throw exception.
saveOrUpdate
This method calls save() or update() based on the operation. If the identifier exists, it will call update method else the save method will be called. saveOrUpdate() method does the following:
- If the object is already persistent in the current session, it do nothing
- If another object associated with the session has the same identifier, throw an exception to the caller
- If the object has no identifier property, save() the object
- If the object’s identifier has the value assigned to a newly instantiated object, save() the object.
2 | import org.hibernate.Session; |
3 | import org.hibernate.SessionFactory; |
4 | import org.hibernate.Transaction; |
5 | import org.hibernate.cfg.Configuration; |
8 | * source : www.javabeat.net |
10 | public class HibernateExample { |
11 | public static void main(String args[]){ |
12 | Configuration configuration = new Configuration(); |
13 | SessionFactory sessionFactory = |
14 | configuration.configure().buildSessionFactory(); |
15 | Session session = sessionFactory.openSession(); |
16 | Transaction transaction = session.beginTransaction(); |
18 | EmployeeInfo employeeInfo = new EmployeeInfo(); |
19 | employeeInfo.setSno( 1 ); |
20 | employeeInfo.setName( "HibernateTestSave" ); |
21 | session.save(employeeInfo); |
25 | session = sessionFactory.openSession(); |
26 | transaction = session.beginTransaction(); |
28 | employeeInfo = new EmployeeInfo(); |
29 | employeeInfo.setSno( 1 ); |
30 | employeeInfo.setName( "HibernateTestUpdate" ); |
31 | session.update(employeeInfo); |
35 | session = sessionFactory.openSession(); |
37 | transaction = session.beginTransaction(); |
39 | employeeInfo = new EmployeeInfo(); |
40 | employeeInfo.setSno( 1 ); |
41 | employeeInfo.setName( "HibernateTestSaveOrUpdate" ); |
42 | session.saveOrUpdate(employeeInfo); |
- Source at: http://www.javabeat.net/difference-between-hibernates-saveupdate-and-saveorupdate-methods
6.Why Hibernate has no args constructor.
The hibernate is an ORM framework which supports field or property access strategy. However, it does not support constructor-based mapping - maybe what you would like ? - because of some issues like
1º What happens whether your class contains a lot of constructors
public class Person {
private String name;
private Integer age;
public Person(String name, Integer age) { ... }
public Person(String name) { ... }
public Person(Integer age) { ... }
}
As you can see, you deal with a issue of inconsistency because Hibernate cannot suppose which constructor should be called. For instance, suppose you need to retrieve a stored Person object
Person person = (Person) session.get(Person.class, <IDENTIFIER>);
Which constructor should Hibernate call to retrieve a Person object ? Can you see ?
2º And finally, by using reflection, Hibernate can instantiate a class through its no-arg constructor. So when you call
Person person = (Person) session.get(Person.class, <IDENTIFIER>);
Hibernate will instantiate your Person object as follows
Person.class.newInstance();
Which according to API documentation
The class is instantiated as if by a new expression with an empty argument list
Moral of the story
Person.class.newInstance();
is similar To
new Person();
Nothing else
http://stackoverflow.com/questions/2935826/why-does-hibernate-require-no-argument-constructor
7.What are different states in Hibernate
1. Transient State: A New instance of a persistent class which is not associated with a
Session, has no representation in the
database and no identifier value is considered
transient by Hibernate:
UserDetail user = new UserDetail();
user.setUserName("Dinesh Rajput");
// user is in a transient state
2. Persistent State: A persistent instance has a representation in the database , an identifier value and is associated with a Session. You can make a transient instance persistent by associating it with a Session:
Long id = (Long) session.save(user);
// user is now in a persistent state
3. Detached State: Now, if we close the Hibernate Session, the persistent instance will become a detached instance: it isn't attached to a Sessionanymore (but can still be modified and reattached to a new Session later though).
session.close();
//user in detached state
Difference between Transient and Detached States:Transient objects do not have association with the databases and session objects. They are simple objects and not persisted to the database. Once the last reference is lost, that means the object itself is lost. And of course , garbage collected. The commits and rollbacks will have no effects on these objects. They can become into persistent objects through the save method calls of Session object.The detached object have corresponding entries in the database. These are persistent and not connected to the Session object. These objects have the synchronized data with the database when the session was closed. Since then, the change may be done in the database which makes this object stale. The detached object can be reattached after certain time to another object in order to become persistent again.Lets see in the following example to save or update the user data...
package com.sdnext.hibernate.tutorial;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import com.sdnext.hibernate.tutorial.dto.UserDetails;
public class HibernateTestDemo {
/**
* @param args
*/
public static void main(String[] args)
{
UserDetails userDetails = new UserDetails();
userDetails.setUserName("Dinesh Rajput");
userDetails.setAddress("Noida City");
//Here 'userDetails' is TRANSIENT object
SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(userDetails);
//Here 'userDetails' is PERSISTENT object
userDetails.setUserName("User Updated after session close");
session.getTransaction().commit();
session.close();
//Here 'userDetails' is DETACHED object
}
}
http://www.dineshonjava.com/p/transient-persistent-and-detached.html#.U_IiAPmSwSk