What you read in this article:
How is the cache implemented in Hibernate?
In this article, I, Arsalan Mirbozorgi want to introduce you to the concept of hibernate in Java and tell you how to use cache in it. In previous Java programming courses, you were introduced to the basic concepts of Java, now we want to have newer concepts in this article for you.
Caching in Hibernate
Another interesting feature offered by Hibernate is caching support. By having and using this feature, you can reduce the requests to the database and increase the efficiency of the program as much as possible. The cache is placed between the application and the database, reducing the number of frequent visits to the database. To summarize, caching in Hibernate reduces the number of requests to the database, which speeds up the program.
Cache in hibernate second level layer
In the figure below you can see that the cache is used in Hibernate on two levels. In this article, we try to examine the cache in the second level of hibernation. To achieve this goal, after giving more details, we will give you a brief introduction about cache in the first level and then we will talk about cache in the second level.
First level cache or first level cache in Hibernate
The first level cache is active in a session and is used in all requests that are exchanged. This level of cache automatically processes all requests before sending them to the database and greatly prevents duplicate transactions with the database. The first level cache features can be summarized for you in the following:
- This level is enabled at the session level by default.
- No special settings needed by programmers.
- Programmers are unable to disable this level.
- This cache is available through all the sessions.
- If the session is disabled, all cached objects will be lost.
- Cached objects cannot share between multiple sessions.
You can see the steps of loading an object in full, in the figure below. In this image, after hibernate receives the request, it checks the existence of the object on the session. If this object is present in the session, the data will be restored from that section. If this object does not exist in the session section, the request goes to the database and the data is recall from the main database, which in this case also creates a cache.
Second level cache or second level cache in Hibernate
In general, the cache in the second level is dependent on the factory session object. All objects are loaded at the factory level during the execution of the transaction. As a result, none of these objects are restricted to the user, and you can use them at all levels of the application. The second level cache features can be summarized for you in the following:
- This level of cache exists by default at the Session Factory object level.
- Requires special settings from programmers.
- Use of this cache is optional.
- For this cache, there are various implementations such as EH Cache, OS Cache, SWARM Cache, JBOSS Cache.
The loading steps of the second level cache are similar to the first level cache. The only small difference between the two in this regard is that if the desired information is not found at the session level, the search is performed at the session factory level, which is wider and more complete. If there is no search result in this section, the request will be transferred to the main database.
We want to test the running of the second level EH cache for you. To do this, we must use the second level cache. Then we add the dependency under the names of the Hibernate-ehcache to the project pom.
Hibernate settings need to be changed. Assuming the factory is singleton, we set the factory class value equal to the EH Cache Reign Factory singleton and activate the second level cache and query cache, and we must also introduce the specific EH Cache settings as a separate xml file to Hibernate.
After that in the settings file (ehcache.xml) we should specify these items.
- In the <diskstore> tag there is a path to the cached content. In fact, this cache is done in the main memory, and this path is where it is used in case of data overflow.
- In the <default cache> tag, the same default settings are run to cache all entities, but if an entity wants to have different settings, these private settings must be introduced to Hibernate in a dedicated <cache> tag.
In the persistence element, the cache strategy is run based on Local Temp Swap. In this way, hibernate uses temporary memory and is emptied when the application is reset automatically.
In every section where the cache is applied on it, a @cache annotation is placed in which, in addition to announcing the cache strategy, a part of the configuration file (ehcache.xml) is introduced to apply the settings.
At this level we get to the running stages of the program. For this purpose, we load the code for 2 objects in different situations, but Simultaneously, we open 2 separate sessions (session B, session A) on Session Factory. Session Factory has a method called get Statistics (). This method has statistical information about all the accidents that may occur on a Session Factory.
To use this information, you should enable them. 3 of this information are in the second level cache and also used in the print Date () method mentioned in the same class.
The get Second Level Cache Hit Count() method returns the number of times an entity was temporarily extracted from the cache. When a record is requested, it first goes to the cache, and if it exists in the cache, it is used and a unit is added to this number.
The Get Second Level Cache Miss Count() method returns the number of failed cache visits. This method shows the number of times the cache has been visited but the record did not exist in the cache.
The get Second Level Cache Put Count() method returns the number of times the entity is cached. This means that when an entity is extracted, a copy of it is cached and the number increases by one.
Another method called the get Entity Fetch Count method is used here. It shows the number of times Fetch requests are sent to the database.
By the breakpoint, we examine the process of running the program from the point specific. Then we load an Employee table record from session A. Then, with the method we wrote, we extract the content of the record and print the statistical information about the cache. Printing query text on the console means pulling out information directly from the bank. As in the statistical information, it can be seen that the request has been sent to the bank. The number of cache withdrawals from Hibernate is zero. Because before this, such a record did not exist in the cache. The number of failed visits to the cache is1 and the number of times stored in the cache is 1too. Because from this moment on, this record stays in the cache.
In the next step you have to reload the same record of the first step. In this method, there is no change in the number of withdrawals from the bank because this record has already been loaded and is in the cache. No changes are made to the cache parameters, and in fact no operations are performed at all.
Next you need to remove the evict loaded on the session using the entity command. In the first level caches where the cache is at the session level and is the default, the cache is completely cleared, but here with removing the entity from the session, the second level cache that is at the factory session level remains. You have to check the printed information. This information is no different from the previous step itself, so as a result of the loss of information on the session, the second level cache remains intact.
In the fourth step you have to run a new record on the session. You can see that this increases the number of extractions per unit and increases the number of withdrawals from the cache of a unit because a new record is placed in the cache.
In the final step, you have to run the first record once in the new session. Carefully, as the cache is shared at the session level, your request will be sent to the database and the record will be removed from the cache.
Due to this, you will encounter an increase in the number of cache extractions, but the number of unsuccessful visits and the number of times saved will remain unchanged.