What is “N+1 Select problem”
In my last two posts, I mentioned that immediate fetching or lazy fetching can cause ‘N+1 select problem’. If you are wondering what exactly is this, read on.
Consider the example of Department and Employees. When you call EntityLoad(”Department”), following sqls will be executed.
SELECT * FROM department;
SELECT * FROM employees WHERE deptId = ?
The first query will be executed once (1) and the second query will be executed as many times as the department (N). Thus the above entityLoad call results into ‘N+1′ sql execution and thus can be a cause of performance bottleneck. Because of N+1 sqls, this is known as ‘N+1 select problem’. This will almost always happen when the fetching is “Immediate” (using fetch=”select”) or can happen with lazy loading.
With immediate fetching it is obvious why this would happen. When lazy=’true”, this can happen when the association is accessed immediately on each of the owning object (department in this case).
If you think this could be happening in your application, use either of these two options.
set lazy=”false” and use fetch=”join” so that the departments and its employees get loaded together. (Eager fetch)
Keep lazy=”true” but load the department using hql with join. So instead of using EntityLoad(”Department”), use
ORMExecuteQuery("from Department dept left join fetch dept.employees")
· The classic N+1 problem in encountered in a simple lazy load scenario in any general application.
1query to get all department objects with PK
SELECT deptID FROM department;
And then query to get all other details of a particular dept
SELECT * FROM department where deptID=?;
The second query is executed as many times (N) as the number of full records you want to fetch. Its when N is high, eager can be a good strategy.
What is Hibernate Proxy
1) Class can be mapped to a proxy instead to a table. When you actually call load on session it returns you proxy. This proxy may contain actual method to load the data.
2) 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
What is the difference between and merge and update
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.
Second Level Cache
Hibernate Session
is a transaction-level cache of persistent data. It is possible to configure a cluster or JVM-level (SessionFactory
-level) cache on a class-by-class and collection-by-collection basis.
usage="transactional|read-write|nonstrict-read-write|read-only"
region="RegionName"
include="all|non-lazy"
/>
you can specify
and
elements in hibernate.cfg.xml
.
Whenever you pass an object to save()
, update()
or saveOrUpdate()
,
and whenever you retrieve an object using load()
, get()
, list()
, iterate()
or scroll()
, that object is added to the internal cache of the Session
.
evict ()
method can be used to remove the object and its collections from the first-level cache
ScrollableResult cats = sess.createQuery("from Cat as cat").scroll(); //a huge result set
while ( cats.next() ) {
Cat cat = (Cat) cats.get(0);
doSomethingWithACat(cat);
sess.evict(cat);
}
What are the id generator classes in hibernate?
A: increment: It generates identifiers of type long, short or int that are unique only when no other process is inserting data into the same table. It should not the used in the clustered environment.
identity: It supports identity columns in DB2, MySQL, MS SQL Server, Sybase and HypersonicSQL. The returned identifier is of type long, short or int.
sequence: The sequence generator uses a sequence in DB2, PostgreSQL, Oracle, SAP DB, McKoi or a generator in Interbase. The returned identifier is of type long, short or int
hilo: The hilo generator uses a hi/lo algorithm to efficiently generate identifiers of type long, short or int, given a table and column (by default hibernate_unique_key and next_hi respectively) as a source of hi values. The hi/lo algorithm generates identifiers that are unique only for a particular database. Do not use this generator with connections enlisted with JTA or with a user-supplied connection.
seqhilo: The seqhilo generator uses a hi/lo algorithm to efficiently generate identifiers of type long, short or int, given a named database sequence.
uuid: The uuid generator uses a 128-bit UUID algorithm to generate identifiers of type string, unique within a network (the IP address is used). The UUID is encoded as a string of hexadecimal digits of length 32.
guid: It uses a database-generated GUID string on MS SQL Server and MySQL.
native: It picks identity, sequence or hilo depending upon the capabilities of the underlying database.
assigned: lets the application to assign an identifier to the object before save() is called. This is the default strategy if no
select: retrieves a primary key assigned by a database trigger by selecting the row by some unique key and retrieving the primary key value.
foreign: uses the identifier of another associated object. Usually used in conjunction with a