Hallo,
ich hätte mal eine frage zu em.merge(T) :
Wenn ich den Sinn dieser Funktion richtig verstanden habe, sollte merge(T) mitteilen, (in etwa) : Hallo liebes Hibernate... hier hab ich dieses (wo anders) persistierte Objekt, könntest du dich darum kümmern, dass es auch in unsere (lokale) DatenBank kommt.
btw, im Objekt das ich persitiere ist mit @Version ein Datum (lastModified) angegeben, sonst autogenerated ID und standard coulmns
Dann wundere ich mich über 2 Sachen : 1. wieso debugt er mir eine update xxx set (bla bla) where id = ? AND lastModified (siehe oben) = ? Also wieso lässt Hibernate beim mergen nach einem lastModified (exakt) suchen... das könnte ja auch ein Datensatz sein, das in der Zukunft (aus der lokalen Sicht) geändert wurde
2. Wenn es schon *unbedingt* exakt dem lastModified entsprechen muss, warum wird dieses feld beim mergen nicht upgedated, wie beim persist ?
Das ganze im Hibernate 4.1.1-final
Test Beschreibung : Ich lese ein Datensatz mit Hibernate. Speiche es in meinem Cache Ändere den Datensatz, und will ihn mit merge wieder persistieren (und um das em.find(..., id) + ändern + persist zu sparen, nur ein merge, weil geladen ist der Datensatz) und dann commit. Soweit gehts ohne probleme. Dann nochmal den gleichen Datensatz ändern und beim 2. merge (in natürlich 2. Transaktion) kommt eine javax.persistence.OptimisticLockException
Ich hab versucht, nach dem 1. merge das lastModified aus der Datenbank zu laden (nachdem es Hibernate nicht schafft...) Ich hab auch versucht nach dem 1. merge das lastModified auf ein new Date() zu setzten (also aktuelle Systemzeit) Ich hab sogar versucht vor dem (1.) merge das lastModified auf new Date() zu setzten
Und bei jedem ein OptimisticLockException. (bei den ersten 2 versuchen erst beim 2. merge, beim 3. versuch schon beim 1. merge)
Und dieses OptimisticLock-check, wird anscheinend ohne DB-zugriff erledigt, denn Hibernate loggt das nicht mit (alle anderen SQL schon)
Die 2 Lösungen die ich sehen würde : 1. em.find(xxx, id) + ändern (2x weil im cache sollte es auch angepasst werden...) + em.persist(T) 2. ein named Query absetzen der genau die geänderten Felder in der DB per update ändert (und eventuell das lastModified gleich auch mit ändert) --- edit ----
eine 3. Möglichkeit wäre, vor dem utx.begin() ein em.clear() zu machen.
was eigentlich eine ganz neue Frage aufwirft : wieso kann ein optimisticLock Problem gelöst werden, wenn man den EntityManager cache löscht ?
--- edit ende ---
Würde mich über antworten freuen.
Und schon im Voraus danke
|