-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: Problem mit Versionierung / Optimistic Locking
PostPosted: Fri Sep 19, 2008 10:18 am 
Newbie

Joined: Fri Sep 19, 2008 9:44 am
Posts: 2
Hi ihrs,

wir sind gerade dabei eines unserer Projekte von JDO nach Hibernate umzustellen und sind da auf ein seltsames Verhalten gestossen, das wir nicht so recht verstehen und uns vor einige Probleme stellt. Ich hoffe, ihr könnt helfen. Folgende Situation:

Wir haben 2 Klassen, Produkt und Lieferant. Ein Produkt beitzt genau einen Lieferanten, Lieferanten wissen nix über ihre Produkte, es ist also eine unidirektionale ManyToOne-Beziehung. Beide Klassen sind versioniert. Das Mapping im Produkt lautet in etwa:

Code:
@Override
    @ManyToOne(targetEntity = LieferantImpl.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "lieferant_id")
    public Lieferant getLieferant() {
       ...
    }


In einem TestCase erstellen wir einen Lieferanten und speichern ihn. Wie erwartet hat der die Version 0. Danach legen wir mehrere Produkte an, die den Lieferanten zugewiesen bekommen.

Bei jedem Speichern eines (neuen) Produkts wird nun die Version des Lieferanten erhöht, was wir nicht so ganz verstehen. Eigentlich hat sich am Lieferant doch nix geändert, der sollte nicht mal wissen, dass er zugewiesen wurde, es handelt sich doch eigentlich um eine unidirektionale Beziehung, die nur das Produkt betrifft.

Nach diesem Vorgang haben wir also die Situation, dass wir mehrere Produkte (detached) mit (eigentlich) demselben Lieferant, aber in unterschiedlichen Versionen besitzen. Wenn wir nun eines der Produkte bearbeiten (nicht den Lieferant, irgendwas anderes) und das speichern wollen, bekommen wir eine StaleObjectStateException, da die Version des Lieferanten nicht stimmig ist. Das ist mittelprächtig ärgerlich.

Das Problem wird sicher auch noch an anderen Stellen auftreten. Daher die Frage: Wie macht man sowas am Besten? Es handelt sich im eine Web-Applikation, bei der es immer mal wieder vorkommen wird, dass Daten (ein Produkt) geladen und detached und erst nach längerer Zeit wieder geschrieben werden. Wenn sich bei jedem ändern/anlegen die Versionen aller abhängiger Entitäten verändern ist bei einem komplexen Objektgraphen die Wahrscheinlichkeit sehr hoch, dass sich mindestens eines der abhängigen Objekte in der Zwischenzeit verändert hat und man das Owner-Objekt (in diesem Fall das Produkt) nicht wieder schreiben kann.

Ich hoffe die Beschreibung war einigermaßen verständlich ;-) Würde mich freuen, wenn jemand da nen Rat oder sogar DIE Lösung hat.

Gruß

Steffen


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 19, 2008 10:35 am 
Expert
Expert

Joined: Thu Jul 05, 2007 9:38 am
Posts: 287
Wenn ihr die join column anotation entfernt funktioniert es (glaube ich) Ich bekommt dann eine Zwischentabelle. So wird es auch von der Hibernate Referenz doku empfohlen.

Alternativ könnt ihr euch natürlich zu beginn jedes Requests, die Daten aus der Db respektive 2nd Level Cache ziehen. (load, get, refresh)

Mir persönlich gefällt die zweite Variante besser, aber das ist wohl Geschmackssache, bzw. Frage der Anforderungen.

Jens

_________________
Please rate useful posts.


Schauderhaft: Softwaredevelopment, Projectmanagement, Qualitymanagement and all things "schauderhaft"


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 19, 2008 12:05 pm 
Newbie

Joined: Fri Sep 19, 2008 9:44 am
Posts: 2
Hallo Jens,

ohne die Join-column gehts leider auch nicht. Dann wird zwar ein Join Table erstellt, das Versionsproblem bleibt jedoch bestehen. Was geht, ist die cascade-Option wegzulassen. Dann verlieren wir aber die Möglichkeit des transitiven Speicherns, was wir eigentlich nicht wollen *seufz*

Hat noch jemand ne Idee?

Was die zweite Variante betrifft: Wie stellst du dir das genau vor? Folgender Anwendungsfall:

1) User fragt Produkt1 an -> Laden des Produkts samt Lieferant aus der DB, Auslieferung an Web-Schicht.
2) User geht Kaffee trinken
3) User ändert den Preis von Produkt1 und will speichern.

Nun stehen wir vor dem Problem, dass inzwischen jemand anderes ein anderes Produkt mit demselben Lieferant geändert haben könnte und demnach das save fehlschlägt wg. falscher Version des Lieferant (nicht des Produkts, hätte jemand Produkt1 in der Zwischenzeit geändert wäre das ja ein korrekter Fall von Optimistic Locking). Also müsste ich mir jetzt eine aktuelle Version von Produkt1 aus der DB holen, das die korrekte Version des Lieferantn besitzt und die Änderungen, die der User gemacht hat (der geänderte Preis) in dieses Produkt übertragen. Dazu bräuchte ich sowas wie ein dynamisches Diff/Merge für Beans, gibts sowas?

Steffen


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.