Yesterday we noticed an issue where a call to EntityManager.merge
for an existing, unattached entity that is presumably not in the session would create a duplicate. This has never happened before or again afterwards, but at that point in time it happened 6 times in a row.
Here is the order of events plus what I deducted from the logs:
- An updated, detached entity (Rule with the ID 9) is received through a request to the REST API
- This entity existed in the database at that point in time
- The application uses a
session-per-request
strategy, the entity has not been touched prior to themerge
call, thus should not be in the session - Merge is called with the detached entity
-
org.hibernate.loader.Loader
tries to load the entity -
org.hibernate.loader.Loader
states that it finished loading the entity, but it seems it could not find it - There are no exceptions or anything else that could indicate that the entity could not be loaded from the database
- Then a new insert is executed, creating a duplicate of the entity with the ID 16
Here is an excerpt of the log for a merge
call, I marked the lines where the Loader is trying to retrieve the entity:
I can show more of the logs if that may be useful.
The method in the REST API:
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@AuthorizationRequired({AccessLevel.CCU_VIEW})
public Rule saveRule(Rule rule) {
ruleEditor.saveRule(rule);
return rule;
}
And in the RuleService
:
@Override
public void saveRule(Rule rule) {
updateAuthorizationChecks.mayEditRule(rule);
if (rule.getId() > 0) {
ruleRepository.merge(rule);
} else {
ruleRepository.persist(rule);
}
updateProjectEvents.ruleEdited(rule);
}
updateAuthorizationChecks.mayEditRule
does not access the entity in question.
So what I do not understand here is how the org.hibernate.loader.Loader
could come to the conclusion that the entity did not exist. Again, this only happened a few times in a row, never before, never again. Can any of you give some insight on how this might have happened? Or how I may be able to reproduce this issue?