While the entities are all within the same navigation and request, you may get different entities due to entity manager flushes when queries are run.
When you execute a query, it can flush the entity manager therefore invalidating the entity manager entity cache.
For example :
MyClass a = entityManager.find(MyClass.class,id); MyList = entityManager.createQuery("...").getResultList(); MyClass b = entityManager.find(MyClass.class,id);
Here, I believe 'a' and 'b' would be different objects representing the same entity with the same id because the query caused a flush which invalidated the cache and caused the entity manager to create and load a new instance of the entity.
What you could try, to diagnose the problem a bit is adding :
If one of them is a stale detached object, then the entity manager will complain.
Ok Andy, first of all many thanks for your reply.
What you wrote is very interesting, but I am not sure about a point: I understand I can get two objects for the same entity during the same request due to some implicit flush before a query (I think this behaviour is controlled by hints), but wouldn't the flushed objects have to return false at EntityManager.contains?
The problem is that I got two "valid" objects for the same entity, that is both contained by the same EntityManager at the same moment.
It seems I found a way to fix it by a better implementation of the methods: compareTo, hashCode and, overall, equals in all my entities, even those I have to navigate to get the duplicated instances: so my understanding (but I ask for confirmation), is that the identity within an EntityManager is kept by using equals and not (as I believed having used some JDO implementation) by using the pair class/id.
I don't know if it depends on a specific implementation, but I think it should be well defined in the JPA standard (I know, this forum could not be the right place for the discussion), since it could have some side effects, or (at least) it would require a more detailed specification about the canonical ways to implements equality, hashing and ordering for the entities.