Hallo,
bei meiner Anwendung gibts pro User eine Stateful Session Bean, mit Session-Scope, die eine Entity hält, welche von dem Benutzer bearbeitet wird. Die zu bearbeitende Entity (JPA-@Entity, also Eintrag einer Datenbanktabelle) wird, wenn sich ein User einloggt, zufällig ausgewählt; um zu verhindern, dass mehrere User versehentlich die gleiche Entity zugeordnet bekommen, hat diese ein boolean-Flag "selected", welches nach Auswahl auf "true" gesetzt wird und wenn der User fertig ist, wieder auf "false".
Probleme bereitet mir nun der Fall, wenn der User sich nicht ordnungsgemäß ausloggt und seine Arbeit beendet, sondern einfach so weggeht oder den Browser schliesst, und die Session Bean letzten Endes durch ein Timeout der HTTP-Session abgeräumt wird. In diesem Fall muss die Entity natürlich auch wieder auf "false" gesetzt werden, da sie ja sonst für alle anderen User gesperrt bleibt, was natürlich nicht beabsichtigt ist.
Nur will das irgendwie nicht funktionieren. Es handelt sich um eine Seam/EJB3-Anwendung, und nach allem was ich so weiss, gibts da zwei Varianten, die so aussehen:
a)
b)
Also unterschiedlich, je nachdem ob man den EBJ- oder den Seam-EntityManager benutzt.
Aber beides funktioniert nicht.. Fehlermeldungen:
a)
06:32:17,078 ERROR [AssertionFailure] an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
org.hibernate.AssertionFailure: cannot copy a reference to an object with a null id
at org.hibernate.type.EntityType.replace(EntityType.java:255)
b)
06:38:30,718 WARN [Component] Exception calling stateful session bean default @Remove method: startProject
java.lang.RuntimeException: javax.persistence.TransactionRequiredException: EntityManager must be access within a transaction
at org.jboss.ejb3.interceptor.LifecycleInterceptorHandler.preDestroy(LifecycleInterceptorHandler.java:135
Was mag da los sein?
Und vor allem: ist mein Ansatz, die Entity in der Destroy/PreDestroy-Funktion zu verändern, überhaupt der richtige? Oder wie macht man sowas normalerweise?
Gruß+Danke
Jan
bei meiner Anwendung gibts pro User eine Stateful Session Bean, mit Session-Scope, die eine Entity hält, welche von dem Benutzer bearbeitet wird. Die zu bearbeitende Entity (JPA-@Entity, also Eintrag einer Datenbanktabelle) wird, wenn sich ein User einloggt, zufällig ausgewählt; um zu verhindern, dass mehrere User versehentlich die gleiche Entity zugeordnet bekommen, hat diese ein boolean-Flag "selected", welches nach Auswahl auf "true" gesetzt wird und wenn der User fertig ist, wieder auf "false".
Probleme bereitet mir nun der Fall, wenn der User sich nicht ordnungsgemäß ausloggt und seine Arbeit beendet, sondern einfach so weggeht oder den Browser schliesst, und die Session Bean letzten Endes durch ein Timeout der HTTP-Session abgeräumt wird. In diesem Fall muss die Entity natürlich auch wieder auf "false" gesetzt werden, da sie ja sonst für alle anderen User gesperrt bleibt, was natürlich nicht beabsichtigt ist.
Nur will das irgendwie nicht funktionieren. Es handelt sich um eine Seam/EJB3-Anwendung, und nach allem was ich so weiss, gibts da zwei Varianten, die so aussehen:
a)
Java:
@In
private EntityManager entityManager
@Destroy
public void cleanup()
{
myEntity.setSelected(false);
entityManager.merge(myEntity);
}
b)
Java:
@PersistenceContext
private EntityManager entityManager
@PreDestroy
public void cleanup()
{
myEntity.setSelected(false);
entityManager.merge(myEntity);
}
Also unterschiedlich, je nachdem ob man den EBJ- oder den Seam-EntityManager benutzt.
Aber beides funktioniert nicht.. Fehlermeldungen:
a)
06:32:17,078 ERROR [AssertionFailure] an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
org.hibernate.AssertionFailure: cannot copy a reference to an object with a null id
at org.hibernate.type.EntityType.replace(EntityType.java:255)
b)
06:38:30,718 WARN [Component] Exception calling stateful session bean default @Remove method: startProject
java.lang.RuntimeException: javax.persistence.TransactionRequiredException: EntityManager must be access within a transaction
at org.jboss.ejb3.interceptor.LifecycleInterceptorHandler.preDestroy(LifecycleInterceptorHandler.java:135
Was mag da los sein?
Und vor allem: ist mein Ansatz, die Entity in der Destroy/PreDestroy-Funktion zu verändern, überhaupt der richtige? Oder wie macht man sowas normalerweise?
Gruß+Danke
Jan