Make delicious recipes!


Caching in Hibernate


Hibernate has several levels of caching in-built into it.

  1. First-level cache (mandatory cache tied to each session):
    First-level cache is mandatory and is tied to a session.
    Every hibernate session delays the actual committing of an object to the database as long as its possible to hold it in cache.
    This reduces the number of update commands to the DB and improves peformance.

    All uncommitted objects are written to the DB if a session is closed.


  2. Second level cache (shared across sessions):
    The second level cache in Hibernate is used in conjunction with another caching tool like EhCache, OSCache, SwarmCache or JBoss TreeCache etc.
    There are four caching strategies to be used in second-level cache:
    1. Read-only: Used where data is very rarely updated.
    2. Read-write: Used when data is more frequently updated than #1 and staleness in reads is undesirable.
    3. Nonstrict read-write: Used when data updates are frequent but it is ok for reads to be stale sometimes.
    4. Transactional: Used when concurrent transactions are frequently expected.

    Example: The cache usage needs to be enabled on a per class basis in each .hbm.xml file
        
    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC 
     "-//Hibernate/Hibernate Mapping DTD//EN"
     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 
    
    <hibernate-mapping>
       <class name="Person" table="PERSON">
          <cache usage="read-write"/>
          <id name="id" type="int" column="id">
             <generator class="native"/>
          </id>
          <property name="name" column="name" type="string"/>
          <property name="age" column="age" type="int"/>
          <property name="ssn" column="ssn" type="string"/>
       </class>
    </hibernate-mapping>
    
    


    Also, the hibernate.cfg.xml configuration file needs a property to be enabled as follows:
    
    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
     
    <hibernate-configuration>
    <session-factory>
    
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:4000/yourdb-SID</property>
        
        <property name="hibernate.connection.username">admin</property>
        <property name="hibernate.connection.password">admin</property>
        
        <property name="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</property>
        
        <property name="show_sql">true</property>
        <property name="format_sql">true</property>
        
        <property name="hibernate.cache.provider_class">
          org.hibernate.cache.EhCacheProvider
        </property>
        
        <mapping resource="Person.hbm.xml" />
        <mapping resource="Student.hbm.xml" />
    </session-factory>
    </hibernate-configuration>
    
    


  3. Query cache (Enabled using second-level cache):
    Every query string (and its bind parameters) are used as a key in second-level cache.
    The value corresponding to this key is a list of the primary keys of all of the entities returned by the query.
    The entire objects corresponding to the primary keys are not kept to avoid the second-level cache getting full too frequently.
    When a query is found in query-cache, these primary keys are looked up in the first-level cache by default and if found there, it gives a high performance gain.

    However, a word of caution.
    Even with the optimization of keeping only primary keys, the query cache can be very memory intensive.
    This is especially true when the bind parameters to the query are objects having references to other objects.

    Also, the query cache for a query is invalidated if any updates are made to the underlying tables.
    So if very frequent writes are expected, then query cache may not be of much help.

    Lastly, query cache can be good if natural key lookups are very frequent.
    Natural keys are those columns which are not primary keys of a table but are still unique per row.
    For example, SSN/PAN/fingerprint in a table of persons is a natural key.
    For such lookups, query-cache can store primary key reference and assume that it will change extremely rarely, thus giving good performance.







Like us on Facebook to remain in touch
with the latest in technology and tutorials!


Got a thought to share or found a
bug in the code?
We'd love to hear from you:

Name:
Email: (Your email is not shared with anybody)
Comment:

Facebook comments:

Site Owner: Sachin Goyal