Can anyone bring an example of a Hibernate session/unit of work in which session cache is useful?
posted 2 years ago
-
-
Number of slices to send:Optional 'thank-you' note:
-
-
From what I understand, a unit of work must be short-lived.
For example, say there is an imaginary application that is used by a school to maintain information about students. Suppose a student's address changed and a clerk needs to change this information in this application.
One unit of work will be to retrieve the student's information.
The clerk enters the new address.
The second unit of work will be to save the new address.
In the above example, which consisted of two units of work, there is nothing useful about the session cache.
I can't think of a scenario in which the session cache would be useful, given that unit of work is supposed to be short-lived. Maybe somebody can bring an example when the session cache would be useful in improving the performance. Thanks in advance.
For example, say there is an imaginary application that is used by a school to maintain information about students. Suppose a student's address changed and a clerk needs to change this information in this application.
One unit of work will be to retrieve the student's information.
The clerk enters the new address.
The second unit of work will be to save the new address.
In the above example, which consisted of two units of work, there is nothing useful about the session cache.
I can't think of a scenario in which the session cache would be useful, given that unit of work is supposed to be short-lived. Maybe somebody can bring an example when the session cache would be useful in improving the performance. Thanks in advance.
posted 2 years ago
-
-
Number of slices to send:Optional 'thank-you' note:
-
-
Well, when you use the term "session" in relation to Hibernate, that makes me think you're using legacy Hibernate, not Hibernate JPA, which uses the term "EntityManager" per the JPA standard, not "Session" (not to be confused with HttpSession). And I really don't know how diligently the Hibernate team has been back-porting performance features from Hibernate JPA to Hibernate anyway.
If your sample application is a web application, you have shown in that example the benefit of a cache. Consider:
1. An Http Request comes in to the server to edit a record. The edit request handler must fetch the record from the database in order to display it. That's your first unit of work. The request handler returns the Http Response and connection is closed.
2. The user makes changes and posts them via a second HttpRequest. The update request handler must fetch that record AGAIN, update it, and then push the updated record back into the database.
To understand why the double-fetch you have to understand how webapps and JPA work.
When you fetch an ORM Entity object, you get a POJO that the webapp display consults as a Model for the display data (View). But when the Http Response is closed, that object has a dilemma. You can keep it in an HttpSession scope object, but to do so, you must disconnect it from the EntityManager/Session. If you do not, you are tying up database connection resources in the hope that the update will come in soon to complete the operation. But in fact, there's no guarantee that the update will come at all. The user may choose not to save and simply skip on to another task. The user might step out to take a long leisurely café lunch. The department may suddenly find itself "right-sized" in the middle of work and the user is being escorted out the door with no opportunity or permission to touch the keyboard and close the operation.
So, let's say that none of the above happens and the second work unit is being processed. You cannot simply update yout HttpSession-scoped saved copy of the Entity because you cannot update a disconnected ORM object. First you have to re-connect to the EntityManager/Session. And when you do that with a JPA merge(), that actually means that an entirely new copy of the object is created using data fetched from the database. Once you invoke merge(), the original Entity object becomes useless and you must work with the copy returned from merge().
As a side note, simply ramming the object back into the database would not work in most cases due to the possiblity of an OpportunisticLockingException.
Also note that since you have to fetch the object again, you don't actually need to keep the entire object in your HttpSession. Just the object's primary key value is enough to re-attach.
So even in such a simple scenario, having some sort of local cache for Entity objects can cut some overhead. Depending on settings, you may still have to go alll the way back to the database again to ensure that there were no concurrent modifications, but that can be avoided if you have the right environment.
If your sample application is a web application, you have shown in that example the benefit of a cache. Consider:
1. An Http Request comes in to the server to edit a record. The edit request handler must fetch the record from the database in order to display it. That's your first unit of work. The request handler returns the Http Response and connection is closed.
2. The user makes changes and posts them via a second HttpRequest. The update request handler must fetch that record AGAIN, update it, and then push the updated record back into the database.
To understand why the double-fetch you have to understand how webapps and JPA work.
When you fetch an ORM Entity object, you get a POJO that the webapp display consults as a Model for the display data (View). But when the Http Response is closed, that object has a dilemma. You can keep it in an HttpSession scope object, but to do so, you must disconnect it from the EntityManager/Session. If you do not, you are tying up database connection resources in the hope that the update will come in soon to complete the operation. But in fact, there's no guarantee that the update will come at all. The user may choose not to save and simply skip on to another task. The user might step out to take a long leisurely café lunch. The department may suddenly find itself "right-sized" in the middle of work and the user is being escorted out the door with no opportunity or permission to touch the keyboard and close the operation.
So, let's say that none of the above happens and the second work unit is being processed. You cannot simply update yout HttpSession-scoped saved copy of the Entity because you cannot update a disconnected ORM object. First you have to re-connect to the EntityManager/Session. And when you do that with a JPA merge(), that actually means that an entirely new copy of the object is created using data fetched from the database. Once you invoke merge(), the original Entity object becomes useless and you must work with the copy returned from merge().
As a side note, simply ramming the object back into the database would not work in most cases due to the possiblity of an OpportunisticLockingException.
Also note that since you have to fetch the object again, you don't actually need to keep the entire object in your HttpSession. Just the object's primary key value is enough to re-attach.
So even in such a simple scenario, having some sort of local cache for Entity objects can cut some overhead. Depending on settings, you may still have to go alll the way back to the database again to ensure that there were no concurrent modifications, but that can be avoided if you have the right environment.
Experience keeps a dear School, but Fools will learn in no other.
---
Benjamin Franklin - Postal official and Weather observer
| Everybody! Do the Funky Monkey! Like this tiny ad! The new gardening playing cards kickstarter is now live! https://www.kickstarter.com/projects/paulwheaton/garden-cards |











