java-forum.org
JBoss Seam
Alter Preis: 39,95 €
Jetzt: 0,00 €

zzgl. Versandkosten

Zurück   java-forum.org > Enterprise Java > Application Tier

Application Tier EJB, Spring

Antwort    
Themen-Optionen Thema durchsuchen Ansicht
Alt 06.03.2010, 05:27   #1 (permalink)
Stammbenutzer
Kilobyte
 
Registriert seit: 21.12.2006
Beiträge: 410
Abgegebene Danke: 0
Erhielt 4 Danke für 4 Beiträge
Standard Session-Bean aufräumen bei Timeout bei Seam/EJB

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)
Java Code: Quelltext in neuem Fenster öffnen
1
2
3
4
5
6
7
8
9
@In
private EntityManager entityManager
 
@Destroy
public void cleanup()
{
   myEntity.setSelected(false);
   entityManager.merge(myEntity);
}

b)
Java Code: Quelltext in neuem Fenster öffnen
1
2
3
4
5
6
7
8
9
@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
JanHH ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 06.03.2010, 11:27   #2 (permalink)
Java-Forum Team
Moderator
 
Registriert seit: 13.09.2007
Beiträge: 8.314
Abgegebene Danke: 6
Erhielt 134 Danke für 132 Beiträge
Zitat:
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?
Du baust dir gerade dein eigenes Pessemistic Locking nach

Abgesehen daovn verstehe ich nicht warum man zu beabeitende Entities zufällig auswählen wollen würde..
maki ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 06.03.2010, 13:03   #3 (permalink)
Stammbenutzer
Kilobyte
Themenstarter
 
Registriert seit: 21.12.2006
Beiträge: 410
Abgegebene Danke: 0
Erhielt 4 Danke für 4 Beiträge
Na ob die nun zufällig ausgewählt werden oder bewusst, sie bleiben gesperrt, wenn der User sich nicht ausloggt oder sie wieder freigibt. Dachte, genau dazu sind diese Funktionen.. Notwendige Aufräumarbeiten, wenn die Session timeout hat. Sehe ich das verkehrt?
JanHH ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 08.03.2010, 13:50   #4 (permalink)
Stammbenutzer
Megabyte
 
Registriert seit: 19.01.2007
Beiträge: 1.563
Abgegebene Danke: 1
Erhielt 36 Danke für 36 Beiträge
Die preDestroy-Methode läuft in einem unspezifiziereten Transaktions- und Securitycontext (siehe EJB Spec). Es ist nicht sichergestellt, dass preDestroy auch aufgerufen wird (Gründe: siehe EJB Spec). Der Beanentwickler darf nur die Callback-Methoden einsetzen, um eigene Arbeiten zu verrichten.

maki hat schon angemerkt, dass du hier etwas "nachbaust". Was ist das für eine Entity? Was wird einem User zugeordnet?
__________________
Grüße,

++++++++++
[
>+++++++>++++++++++>+++>+<<<<-
]
>.
-----.
>++++++++++++++.
++.

So funktioniert das mit Foren/Newsgroups/Mailing Lists etc.:
smart-questions_de
FArt ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 10.03.2010, 10:44   #5 (permalink)
Stammbenutzer
Kilobyte
Themenstarter
 
Registriert seit: 21.12.2006
Beiträge: 410
Abgegebene Danke: 0
Erhielt 4 Danke für 4 Beiträge
Naja der Anwendungsfall ist doch eigentlich relativ einfach. Ein User wählt einen Datensatz aus um diesen zu bearbeiten, diese Bearbeitung kann recht lange dauern, und während dieser Zeit muss sichergestellt sein, dass dieser Datensatz nicht zur Auswahl für andere User zur Verfügung steht. Also muss er irgendwo als "gerade in Bearbeitung" markiert werden. Wenn der User den Vorgang ordnungsgemäß abschliesst, ist alles ok. Wenn er einfach das Browserfenster schliesst und wegläuft, bleibt der Datensatz als "in Bearbeitung" markiert, was natürlich nicht so sein soll. Daher bleibt da nur, beim Session Timeout des Users, den Datensatz wieder freizugeben.

So mal ganz prosaisch formuliert ,).

Wie löst ihr denn sowas? Ich habs jetzt hingekriegt, allerdings auf eine etwas "unkonvetionelle" Art.

Geändert von JanHH (10.03.2010 um 10:46 Uhr)
JanHH ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 11.03.2010, 09:02   #6 (permalink)
Stammbenutzer
Megabyte
 
Registriert seit: 19.01.2007
Beiträge: 1.563
Abgegebene Danke: 1
Erhielt 36 Danke für 36 Beiträge
Das über Locking zu lösen ist schon ok. Es muss aber nicht persistent sein.

Entweder die User holen sich die Datensätze nicht, sondern bekommen sie z.B. über eine Factory (und melden ein Ende der Arbeit). Meldet sich der User nicht mehr zurück, wird mit dem Ende der Session die Ressoruce wieder freigegeben. Zu realisiern mit einer einfachen Collection, in der die aktiven DS enthalten sind.

Wenn sich der User die DS selber holen muss, kann man das immer noch ähnlich realisieren, inem der User die DS erst registrieren muss. Man kann dann auch (wenn nötig) sicherstellen, dass Änderungen nur an registrierten Objekten und nur von dem registrierten User erlaubt sind.

P.S.: dem fachlichen Objekt direkt ein Attribut "selected" zu verpassen ist eine unschöne Vermischung ... das könnte man z.B. dekorieren ...
__________________
Grüße,

++++++++++
[
>+++++++>++++++++++>+++>+<<<<-
]
>.
-----.
>++++++++++++++.
++.

So funktioniert das mit Foren/Newsgroups/Mailing Lists etc.:
smart-questions_de
FArt ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 11.03.2010, 09:31   #7 (permalink)
Stammbenutzer
Kilobyte
Themenstarter
 
Registriert seit: 21.12.2006
Beiträge: 410
Abgegebene Danke: 0
Erhielt 4 Danke für 4 Beiträge
Doch, das Attribut "Datensatz wurde schon benutzt" soll persistent in der Datenbank stehen. Das ist auch für einige andere Dinge notwendig (z.B. eine Übersicht, wieviele Datensätze schon verwendet worden sind, und wieviele noch unangetastet sind).

Das Problem scheint nur zu sein, eine Methode aufzurufen, die bei session timeout eine Datenbankaktion durchführt. Das habe ich allerdings hinbekommen, wenn auch auf eine absolut unelegante Art. Definitiv nur eine Notlösung. Es wird ganz brutal per Hand eine JDBC-Verbindung aufgebaut, und da dann ein SQL-Statement durchgeführt. Und das innerhalb eines EJB Application Servers...
JanHH ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Antwort    

Lesezeichen

Latex Maths & Physics Editor ...

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln
Es ist Ihnen erlaubt, neue Themen zu verfassen.
Es ist Ihnen erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are aus
Pingbacks are aus
Refbacks are aus


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Fehler beim Starten von Eclipse ide? IDEs und Tools 5 15.04.2008 19:56
Umstellung eines(riesen)Programmes auf Java:Was bietet Java Adventstee Allgemeine Java-Themen 18 14.03.2008 20:07
Socket Kaladial Netzwerkprogrammierung 14 17.09.2007 14:52
Stateful Session Bean Cinimod Allgemeines EE 0 25.08.2005 14:38
Jetspeed@Tomcat Installationsprobleme KSG9|sebastian Server einrichten und konfigurieren 5 23.12.2004 14:10


Alle Zeitangaben in WEZ +2. Es ist jetzt 10:01 Uhr.


Powered by vBulletin® Version 3.8.6 (Deutsch)
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.2
Thanks for Smilies by smilies.4-user.de