Showing posts with label Hibernate. Show all posts
Showing posts with label Hibernate. Show all posts

Friday, January 15, 2016

Logging Hibernate Query

To log Hibernate SQL queries, we need to set below properties to true in the configuration of the session factory (only the first one is mandatory).

<property name="hibernate.show.sql" value="true" />
<property name="hibernate.format.sql" value="true" />
<property name="hibernate.use.sql.comments" value="true" />

show.sql : logs SQL queries
format.sql: pretty prints the SQL
use.sql.comments: adds explanatory comment

This is how a sample query will look like, after enabling above properties:

/* insert com.co.orm.AuditLogRecord  */
insert into 
audit_log
(creationTime, createdBy, deleted, name, operationType, rowId, details)
values
(?,?,?,?,?,?,?,?)

Decoding Above Query

Hibernate logs above query which gets sent to the JDBC driver. Hibernate logs prepared statement and that's why you are seeing? instead of the actual values.

Hibernate only knows about the prepared statement that it sends to the JDBC driver.  It's JDBC driver that builds the actual query and sends them to the database for execution.

This means that, if you want Hibernate to log the actual SQL query with the value embedded, it would have to generate them for you just for logging! 

If you want to see actual query:

Thursday, December 31, 2015

Hibernate write-behind technique

Hibernate implements a technique known as write-behind, to minimize the impact of network latency and duration of database lock.  This enables hibernate makes DML calls as late as possible.

What it actually means is: When objects associated with a persistence context are modified (by update/delete), the changes are not propagated immediately to the database.

Benefits of this technique

  1. If you made two updates to an entity in a session; hibernate doesn't have to make two SQL updates. It can manage both in the same update. 
  2. Hibernate can make use of JDBC batch update when it executes multiple INSERT, UPDATE or DELETE.
  3. Repeated flushing (synchronization of a persistence context with the database) of the persistence context also impacts performance. All dirty objects in the persistence context need to be detected (at the flush time), so if the size of persistent context is large then dirty checking can cause a lot of performance penalty. 

Monday, December 28, 2015

Persistence Context

Java Persistence API uses javax.persistence.EntityManager to manage Entity instances and their life cycle(and hibernate does it using org.hibernate.Session). Each EntityManager instance is associated with a Persistence Context. 

EntityManager begines a new Persistence Context with each transaction and once the transaction ends (with commit or rollback) Context also ends. Within the transaction, entities retrieved from DB are managed entities (or instances which get saved become managed as well). When transaction completes, all entities loose their association from context and become detached.  

So, Persistence Context is cache of managed entity instances attached with your unit of work (or transaction). We don't need to do anything to enable it, it's always there (and we can't turn it off)! This Context has scope of a unit of work and it gets processed in a single thread (so it doesn't have issues like lock management or concurrent access).




How does it help

  • If we ask to load an entity using a primary key, EntityManager/Session checks first in the Context- If the entity is found there, there will be no DB hit. It's repeatable read for the application. So we get repeatable read absolutely free!
  • At most single object (entity) can represent any database row; there is no conflict. And all changes made to that row can be safely written back. 
  • Changes made to a managed entity is immediately visible to other (managed) entities in the context. 
  • At the end of transaction, JPA providers like Hibernate scans persistence context to find out which all entities got modified and only entities with any modification (or dirty attribute) gets propagated to the database. This is known as automatic-dirty-checking

Final Note

Persistence Context hold a copy/snapshot of each persistence object. The snapshot is used by JPA provider to do dirty checking (detect any modification done to the object). So if you carelessly load large number of objects you might run out of memory (OutOfMemoryException).  So be mindful of the impact on memory when you load records from DB (put proper condition in queries to avoid un-necessary load). 


References
https://docs.jboss.org/hibernate/orm/4.0/devguide/en-US/html/ch03.html