EntityManager.merge creates duplicates

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 the merge 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?

First, you need to replicate it using this test case template.

If you can do that, you should open a Jira issue.