Hey everyone,
I am running an application that has been using Hibernate since 2005 or so. A few weeks ago I decided to get the dreaded criteria API migration behind me and went straight from 5.6 to 6.6. Last week I was ready to start initial load tests with real’ish data and immediately saw the logs littered with StaleObjectStateExceptions. I tried a whole lot of things to resolve the issue. And I got the number of exceptions down quite a bit. But since the code/logic as such hasn’t changed - short of migrating some queries to the new criteria API - I am trying to understand where this problem is coming from.
Here’s a rough outline of what my code does, logically:
- The code does scheduling for aircraft.
- For a given aircraft, belonging to a given company, it loads all existing flights as well as the desired flight plan.
- It generates all the flights missing in the near future.
- It then goes over all existing and new flights and makes sure they can be operated
- It adds delays, cancels flights or adds transfers to make the overall flight plan work.
Interestingly, the StaleObjectStateExceptions never relate to the aircraft or their flights. It’s always an airline that shows up in the error. And in the majority of cases, it isn’t the direct operator of the aircraft, but a related company. Some context, with an emphasis on things that I think might be related to the issue:
- Each aircraft has an
operator
(ManyToOne) of typeEnterprise
- Each
Enterprise
has an attributeparentCompany
(ManyToOne) of typeCompany
- That
parentCompany
always is anEnterprise
Enterprise
is a sub-class ofCompany
Company
is a sub-class ofAddressee
- The hierarchy is mapped as a
@Inheritance(strategy = InheritanceType.JOINED)
- Optimistic locking is enabled through a
@Version private Long version;
onAddressee
Now, the operator
of an aircraft is actually modified during flight planning, but not always. But the parent companies almost certainly aren’t (and we never had this this issue in near 20 years of running this code). And yet, it now seems that Hibernate is overly cautious and assumes they have changed, causing these exceptions left and right.
The most effective change I have tried to far was setting the parentCompany
attribute to be lazy-loaded. This reduced the amount of exceptions quite a bit, but it didn’t alleviate the problem completely.
So I would like to understand what might be causing this and what can be done to decrease the chances of this happening. Is my versioning set up correctly? Does my inheritance mapping require a review? Is there a way to to “help” Hibernate to make the right call?
I would be very thankful for your insights.