I have an interesting problem that I discovered when deleting an object and then calling saveOrUpdate on it. I started to get exception "Found two representations of same collection." I did some digging around and found a jira issue was open some time back to fix this problem. Most people who had this problem were getting it for different reasons than me. I was using hibernate 3.2 which already had the fix anyway. I simply was doing the following. processFoo is configured as a transaction
Code:
public void processFoo(Event f){
....
//in my action class
Foo f = (Foo)f;
f.getPlayers().remove(player);
if(f.getPlayers() == 0)
{
hibernateTemplate.delete(f);
}
...
//some where else in the workflow framework
//but before transaction has eneded
hibernateTemplate.saveOrUpdate(f)
}
After debugging Colletions.java where the error was thrown i see the EntityEntry showing that the same object i deleted has its status as MANAGED, whats also interesing is that in
DefaultFlushEntityEventListener.onFlushEntity 2 different objects pointing to the same Foo class is trying to flush one is flaged DELETED and the other is MANAGED. It seems when the MANAGED Foo object tries to flush, the collections linked to it go haywire because the object is no longer persisted.
Digging a few events back within the code when saveOrUpdate is called an I see in the
ActionQueue my object scheduled to delete but then i also see the same object being scheduled for Insertion but with a different id as if it thinks that this is a new Object that needs to be persisted. Hibernate see it as transient and attempts to create one. 2 Foo objects now exist one not in the persistantContext and cannot be looked up when flushing hence my exception. Exception doesnt happen when saveOrUpdate is called but when transaction has ended do i get it. saveOrUpdate seems to just queue these events with ActionQueues and once transaction has ended it then tries to flush the the same object with the id which throws the exception. I removed saveOrUpdate and it worked fine. when transaction has ended the Foo object has been marked for deleted and any other object changes were persisted. So is this a general rule that there is no need to explicitly call saveOrUpdate when in a container managed transaction like Spring in my case?
saveOrUpdate is not my doing but was already part of some larger framework which always updates at the end of a workflow.