Hibernate Learning Notes: Level 2 Cache

Keywords: Hibernate Session xml JDBC

The table for this example query is Hibernate Learning Notes (6): Many-to-One Mapping and One-to-Many Mapping Table used.

Test program CacheDemo.java:

package com.hibernate.cache;

import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.Test;

/**
 * Hibernate Cache provided
 * 	There is a first-level cache and a second-level cache.
 * 	The purpose is to reduce the number of visits to the database and improve the efficiency of program execution.
 *
 * Level 1 cache:
 * 	Based on the Session-based caching, the cached content is only valid in the current session, the session is closed, and the cached content is invalid!
 * 	Characteristic:
 * 		The scope of action is small! Caching time is short.
 * 		Caching effect is not obvious.
 *
 * Level 2 cache:
 * 	Hibernate Application-level caching is provided, which can span multiple sessions, i.e. different sessions.
 * 	    Cached data can be accessed. This swap is also called a secondary cache.
 * 	Hibernate The secondary cache provided has a default implementation and is a pluggable cache framework! If the user wants to use a secondary cache, he only needs to
 * 	    Configure in hibernate.cfg.xml; remove the configuration without affecting the code.
 * 	If users feel that the caching framework provided by hibernate is not working well, they can replace other caching frameworks or implement caching frameworks themselves.
 *
 *  Secondary cache usage steps:
 *      1,Open secondary cache;
 *      2,Specify the cache framework;
 *      3,Open the query cache;
 *      4,Specify which classes are added to the secondary cache;
 *      5,Test code;
 */
public class CacheDemo {

    private static SessionFactory sessionFactory;
    static {
        sessionFactory = new Configuration()
                .configure()
                .addClass(Dept.class) // Automatic loading of mapping files (used in testing)
                .addClass(Employee.class)
                .buildSessionFactory();
    }

    /**
     * Test Level 2 Cache
     */
    @Test
    public void test1() {
        // The first session object
        Session session1 = sessionFactory.openSession();
        Transaction transaction1 = session1.beginTransaction();

        // Query data using the first session:
        Dept dept = (Dept) session1.get(Dept.class, 1);
        System.out.println(dept);

        transaction1.commit();
        session1.close();

        System.out.println("------------------------------");

        // The second session object
        Session session2 = sessionFactory.openSession();
        Transaction transaction2 = session2.beginTransaction();

        // Use the second session query:
        dept = (Dept) session2.get(Dept.class, 1);
        System.out.println(dept);

        transaction2.commit();
        session2.close();
    }
}

1. Without configuration of secondary cache, hibernate.cfg.xml is as follows:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <!-- Database Connection Configuration -->
        <property name="connection.url">jdbc:mysql://localhost:3306/hib_demo</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>

        <property name="show_sql">true</property>       <!-- display sql Sentence -->
        <property name="hbm2ddl.auto">update</property> <!-- Automatic tabulation -->
    </session-factory>
</hibernate-configuration>

Although session query data will be put into the first-level cache, but the first-level cache is session-level cache, different sessions have different caches, and can not share data;

So without configuring the secondary cache, the CacheDemo above runs to generate two sql statements, as follows:

 

2. When configuring the secondary cache, hibernate.cfg.xml is as follows:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <!-- Database Connection Configuration -->
        <property name="connection.url">jdbc:mysql://localhost:3306/hib_demo</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>

        <property name="show_sql">true</property>       <!-- display sql Sentence -->
        <property name="hbm2ddl.auto">update</property> <!-- Automatic tabulation -->

        <!--
            Level 2 cache configuration:
        -->
        <!-- Open Level 2 Cache: Level 2 Cache does not open by default -->
        <property name="hibernate.cache.use_second_level_cache">true</property>
        <!-- Specify which cache framework to use (provided by default) -->
        <property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
        <!-- Open Query Cache -->
        <property name="hibernate.cache.use_query_cache">true</property>

        <!--
            Specify which classes need to be added to the secondary cache
            Caching strategy:
                read-only: Put the object into the second level cache, read-only;
                nonstrict-read-write: Non-strict reading and writing;
                read-write: Objects that can be read and written into the secondary cache;
                transactional: Transaction-based strategy( hibernate 3.6 Version does not support)
        -->
        <class-cache usage="read-write" class="com.hibernate.cache.Dept"/>
    </session-factory>
</hibernate-configuration>

Because the secondary cache is an application-level cache, all session s can access the cached data, so after configuring the secondary cache, the above CacheDemo is executed to generate only one sql statement, because the second query is the data directly obtained from the cache, as follows:

 

Caching strategy:

<class-cache usage= "read-only"/>: objects placed in the secondary cache, read-only;

<class-cache usage= "non strict-read-write"/>: non strict reading and writing;

<class-cache usage= "read-write"/>: objects that can be read and written into the secondary cache;

<class-cache usage= "transactional"/>: Transaction-based strategy (hibernate version 3.6 does not support)

If the caching policy is read-only, the following:


The test program CacheDemo.java was changed to read as follows:

    @Test
    public void test1() {
        // The first session object
        Session session1 = sessionFactory.openSession();
        Transaction transaction1 = session1.beginTransaction();

        // Query data using the first session:
        Dept dept = (Dept) session1.get(Dept.class, 1);
        System.out.println(dept);

        transaction1.commit();
        session1.close();

        System.out.println("------------------------------");

        // The second session object
        Session session2 = sessionFactory.openSession();
        Transaction transaction2 = session2.beginTransaction();

        // Use the second session query:
        dept = (Dept) session2.get(Dept.class, 1);
        dept.setDeptName("Marketing Department"); // Modify the data in the secondary cache
        System.out.println(dept);

        transaction2.commit();
        session2.close();
    }

Because the data queried by the second session is from the secondary cache, dept.setDeptName("Marketing Department") is modifying the data in the secondary cache, and the strategy of the secondary cache is read-only, so the following errors will occur:

Posted by jponte on Fri, 06 Sep 2019 02:46:19 -0700