tranaction problem
martink Mar 10, 2010 3:23 PMHello,
I have a problem with a tranaction.
I have a long runnin conversation. Whenever I get into this conversation and edit an AperakValidierungFeld, it only works for the first time. The second time, I get this stack trace:
Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.rwe.pokos.entity.validation.AperakValidierungFeld#259]
at org.hibernate.event.def.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:261)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:120)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:53)
at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:677)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:661)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:665)
at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:227)
... 128 more
So I think the transaction from the first time is still active. But I don't understand why. The method I call is this one:
public String saveCurrentFeld()
{
String lResult;
this.update();
Long lID = this.currentFeld.getId();
InvalidValue[] lMessages;
ClassValidator<AperakValidierungFeld> lValidator =
new ClassValidator<AperakValidierungFeld>(AperakValidierungFeld.class);
lMessages = lValidator.getInvalidValues(this.currentFeld);
int lCount = (lMessages != null ? lMessages.length : 0);
if (lCount <= 0)
{
if(!this.currentFormat.getFelder().contains(this.currentFeld))
{
this.currentFeld.setNachrichtenformat(this.currentFormat);
this.currentFormat.addFeld(this.currentFeld);
}
for(AperakValidierungInhalt inhalt: this.currentFeld.getInhalte())
{
inhalt.setFeld(this.currentFeld);
if(inhalt.getId() == null)
{
this.entityManager.persist(inhalt);
}
else
{
inhalt = this.entityManager.merge(inhalt);
}
}
if (lID == null)
{
this.entityManager.persist(this.currentFeld);
}
else
{
this.currentFeld = this.entityManager.merge(this.currentFeld);
}
lResult = "savedFeld";
this.currentFeldId = null;
}
else
{
this.showErrors(lMessages);
lResult = null;
}
return lResult;
}
It is in a Bean with this annotations:
@Scope(ScopeType.CONVERSATION)
@Stateful
The @TransactionAttribute should be default by REQUIRED
. I tried to change there a lot, but nothing really helped.
In the saveCurrentFeld
-method I have this.update() at the beginning. If I delete this, I can't edit a AperakValidierungFeld by the first time. With the update it works one time and then the exception is thrown. My understanding was, that the transaction should start and commit/stop within this method because of the @TransactionAttribute-setting. This is the only method I call in this conversation, so it can't come from another method. In this method I merge also AperakValidierungInhalt-entities. Can it be, that it starts several transactions because of this?
I also tried to commit the transactions manually, but on a getTransaction call on the entityManager I get this exception:
javax.ejb.EJBTransactionRolledbackException: JTA EntityManager cannot access a transactions
I tried also with nested conversation, but didnt help.
The entity beans have bi-directional many2one and one2many annotations and have @version fields.
It would be very nice if someone could help me here.
Thx
Martin