hibernate internal cache

hibernate cache is divided into two levels: level cache (session) and the secondary cache (sessionFactory level)
The role of cache is mainly used to improve performance, can be simply understood as a Map; the use of caching involves three steps: Add put data cache access to data from the cache, delete cache invalid data.
Level cache, Session-level sharing.
save, update, saveOrUpdate, load, get, list, iterate, lock will be the object of these methods on a cache. Level cache can not control the amount of cache, so attention should be paid to high-volume operation data may be caused by memory overflow; can evict, clear method to clear the contents of the cache.
Example:

Person p = (Person)s.get(Person.class, id);
Person p = (Person)s.get(Person.class, id);

Implementation of the two consecutive statements, sql statement select query, only one output. Note one of the first query is to use data cache.

query not be able to access data from the cache. Check data from the cache are limited. Put data into the cache has a lot of ways.

static void query(int id) {
        Session s = HibernateUtil.getSession();
        Transaction tx = s.beginTransaction();
        Worker worker = (Worker) s.get(Person.class, id);
        Worker worker2 = (Worker) s.get(Worker.class, id);
        tx.commit();
        System.out.println(worker.getWork_year());
    }

Run the code above, the implementation of the sql statement as follows:

Hibernate: select person0_.id as id8_0_, person0_.name as name8_0_, person0_.age as age8_0_, person0_.work_year as work1_9_0_, person0_.farm_name as farm1_10_0_, person0_.clazz_ as clazz_0_ from (select null as work_year, id, age, name , null as farm_name, 0 as clazz_ from person union select work_year, id, age, name, null as farm_name, 1 as clazz_ from worker union select null as work_year, id, age, name, farm_name, 2 as clazz_ from farmer) person0_ where person0_.id =?


The implementation of two s.get (), but only a select statement shows that the second was taken from the cache data.

session of the evict method for removal of the corresponding cache object. session of the clear method to clear the entire session cache.
Defect level cache: The cache does not limit the amount of data. The cumulative amount of data constantly, resulting in memory overflow. Nothing to protect, share a rather small scope. Cache for a period longer than short-term. Generally exist in a request.

Secondary cache, sessionFactory class sharing
hibernate cache secondary cache to the third-party framework to deal with.

Open hibernate secondary cache, the configuration file in the hibernate configuration. But by default the secondary cache are open:
<property name="hibernate.cache.use_second_level_cache"> true </ property>

For the pluggable implementation, by modifying the parameters to change cache.provider_class;
Cache provider configuration, is generally a third-party caching framework:
<property name="hibernate.cache.provider_class"> org.hibernate.cache.OSCacheProvider </ property>
At pre-configured to confirm the use of cached jar package should be imported into the project.

Also configure the required cache categories: There are two ways.
① In the hibernate configuration file specified:
<class-cache include="all" usage="read-only"/>
Category must be the fully qualified name. cache usage that strategy has four optional value.
Note: The content of element type "session-factory" must match "(property *, mapping *, (class-cache | collection-cache) *, event *, listener *)"-type configuration of the cache must be at maping file configuration behind, or else they will error.
② In the mapping file is specified:
<hibernate-mapping package="hibernatetest">
<class name="User" table="`user`">
<cache usage="read-only"/>
<id name="id">
<generator/>
</ id>
.......

hibernate built on EhCache, OSCache, TreeCache, SwarmCache support, can achieve CacheProvider and Cache interface to add Hibernate does not support the implementation of the cache.

Verification:

public class Main (
static User query (int id) (
User user = null;
Session session = null;
try (
session = HibernateUtil.getSession ();
Transaction tx = session.beginTransaction ();
user = (User) session.get (User.class, id);
System.out.println (user.getUserName ());
user = (User) session.get (User.class, id);
tx.commit ();
session.clear ();
) Finally (
if (session! = null) (
session.close ();
)
)

Session s = null;
try (
s = HibernateUtil.getSession ();
Transaction txn = s.beginTransaction ();
user = (User) s.get (User.class, id);
txn.commit ();
) Finally (
if (s! = null) (
s.close ();
)
)
return user;
)
public static void saveUser (User user) (
Session session = HibernateUtil.getSession ();
Transaction tx = session.beginTransaction ();

Name name = new Name ();
name.setFirstName ( "firstName");
name.setLastName ( "lastName");
user.setUserName (name);
session.save (user);
tx.commit ();
session.close ();
)

public static void main (String [] args) (
User user = new User ();
user.setBirthday (new Date ());

saveUser (user);
query (1);
Statistics st = HibernateUtil.getSessionFactory (). GetStatistics ();
System.out.println ( "put:" + st.getSecondLevelCachePutCount ());
System.out.println ( "hit:" + st.getSecondLevelCacheHitCount ());
System.out.println ( "miss:" + st.getSecondLevelCacheMissCount ());
System.out.println (st.getConnectCount ());
)
Prior to the use of statistical information in the hibernate configuration file configuration:
<property name="hibernate.generate_statistics"> true </ property>

Do not set the output cache will print sql statement. I set up a cache, but can not query, and even a select statement does not. sql statement as follows:
Hibernate: insert into user (first_name, last_name, birthday, id) values (?,?,?,?)
hibernatetest.Name @ 12a55aa
put: 1
hit: 2
miss: 0
3

Later, the user's primary key to generate a conversion to native (one start to use hilo)
Output of sql statement as follows:
Hibernate: insert into user (first_name, last_name, birthday) values (?,?,?)
Hibernate: select user0_.id as id0_0_, user0_.first_name as first2_0_0_, user0_.last_name as last3_0_0_, user0_.birthday as birthday0_0_ from user user0_ where user0_.id =?
hibernatetest.Name @ e0cc23
put: 1
hit: 1
miss: 1
3

The results of two different. This is the generation of primary key way.
Analysis:
session of the save (this method does not fit native way to generate primary key)
The native of the primary key generation methods, the preservation of objects in the procedure did not put the data into the secondary cache go. hibernate in the query data, first session, namely a cache search, if there is on the back. If not found, then go to the secondary cache, if found then return. If still not found, will set up a connection to the database to query. At first query, the two are not cached, so there will be a miss. Through the establishment of connectivity at access to data in both primary and secondary data cache. So print out put: 1, then turn off the session after a cache no longer exists. Query again, although no corresponding level cache data, but eventually be able to get in the secondary cache data, so to achieve a hit, so print out a hit: 1.
However, the use of high and low key way to generate primary key will save when you put data into the cache the go. So there will be a put. So each query can be found in the secondary cache data, so hit 2 times, print hit: 2, miss: 0.
The results also show the number of connections for 3 times, our program was 3 times session.

Summary:
session of the save (this method does not fit native way to generate primary key)
update, saveOrUpdate, list, iterator, get, load, and Query, Criteria will fill the secondary cache, but only (not open when the query cache) Session of the iterator, get, load from the secondary data cache access (iterator may exist N +1 queries).

Query, Criteria (query cache) because of a lower percentage of hits, because the same query will be hit, which are generally not common. So the default is turn off hibernate; modify cache.use_query_cache for true open for query cache, and call query.setCacheable (true) or criteria. setCacheable (true).
SessionFactory provided evictXXX () method used to clear the cache content.
Statistical information to open generate_statistics, with sessionFactory.getStatistics () to obtain statistical information.

There is time to go look at the distributed cache and the central cache.
Conditions for the use of cache
1, amend to read than
2, data volume should not exceed the amount of memory
3, the data should have exclusive control
4, can tolerate the emergence of invalid data