![]() |
|
|
|||||||
| Application Tier EJB, Spring |
|
|
|
Themen-Optionen | Thema durchsuchen | Ansicht |
| #1 (permalink) | |||||
|
Stammbenutzer
Kilobyte
Registriert seit: 21.12.2006
Beiträge: 410
Abgegebene Danke: 0
Erhielt 4 Danke für 4 Beiträge
|
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 |
||||
|
|
|
| #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
|
![]() Abgesehen daovn verstehe ich nicht warum man zu beabeitende Entities zufällig auswählen wollen würde.. |
|||||||||||||||
|
|
|
|||||||||||||||
| #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?
|
|
|
|
| #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 |
|
|
|
| #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) |
|
|
|
| #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 |
|
|
|
| #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... |
|
|
|
|
| Lesezeichen |
Latex Maths & Physics Editor ...
|
| Themen-Optionen | Thema durchsuchen |
| Ansicht | |
|
|
Ä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 |