Hibernate @ OneToMany mit mappedBy (Parent-Child) Beziehung und Cache-Problem

8

Ich habe dieses Problem schon lange, ich habe das Internet und SO rein und raus gesucht und noch keine Lösung gefunden. Ich hoffe du kannst mir dabei helfen.

Ich habe eine Eltern-Kind-Beziehung zwischen zwei Entitäten wie folgt:

%Vor%

Die Sache ist, dass, wenn ich ein neues Kind erstelle und es einem Elternteil zuweise, das Elternteil nicht aktualisiert wird, wenn es bereits im Cache ist.

%Vor%

Ich habe versucht, @PreUpdate zu verwenden, um das untergeordnete Element automatisch dem übergeordneten Element hinzuzufügen, wenn das untergeordnete Element beibehalten wird. In dem Fall, in dem zwei Entitätsmanager in zwei verschiedenen Threads (wie in JBoss) vorhanden sind, besteht das Problem jedoch weiterhin Wir rufen em.refresh(parent)

auf

Die Frage ist also - gibt es eine Möglichkeit, das Problem reibungslos zu beseitigen und sicherzustellen, dass parent.getChildren() immer die aktuelle Liste der Kinder zurückgibt?

    
artemb 30.07.2009, 13:00
quelle

3 Antworten

8

Die meisten ORMs werden sich so verhalten.

Das Objekt im Cache wird nicht von der Datenbank aktualisiert (ein zusätzlicher Lesevorgang ist nicht erforderlich). Denken Sie auch an das Objektmodell und die Persistenz als getrennt. Halten Sie Ihr Objektmodell mit sich selbst konsistent und verlassen Sie sich nicht auf den Persistenzmechanismus, um dies für Sie zu tun.

Wenn Sie also möchten, dass das Objekt zur Sammlung hinzugefügt wird, dann tun Sie das im Code "setParent".

Die beste Praxis in diesem Fall ist in der Tat, dass eine Seite der Beziehung die ganze Arbeit macht und sich die andere Seite auf die Seite stellt. Außerdem würde ich vorschlagen, Feldzugriff statt Methodenzugriff zu verwenden, damit Sie Methoden mit größerer Flexibilität anpassen können.

Fügen Sie dem übergeordneten Element addChild

eine Methode hinzu %Vor%

und dann setParent in Child:

%Vor%

setParent0 in Child ist der Eigenschaftenstarter für das übergeordnete Element.

%Vor%

Ich würde auch vorschlagen, dass die "getChildren" -Methode eine unveränderbare Sammlung zurückgibt, so dass Entwickler diese Methode nicht versehentlich verwenden (ich habe den harten Weg in all dem gelernt).

Noch eine Sache, Sie sollten null Prüfcode und andere defensive Teile in dem obigen Code haben, ich habe es aus Gründen der Klarheit weggelassen.

    
Michael Wiles 30.07.2009, 14:42
quelle
4

Ziemlich sicher, dass Ihr Problem hier Ihre Cascade-Einstellungen ist.

%Vor%

Wenn Sie diese Kaskadeneinstellungen verwenden, wird die Kaskadierung beibehalten und auf untergeordnete Objekte aktualisiert.

z.

%Vor%

oder

%Vor%

Weitere Informationen hierzu finden Sie unter Hibernate Annotations

    
Michael Allen 28.09.2011 12:55
quelle
1

In Bezug auf Ihr Problem beim Zwischenspeichern ist dies ein sehr häufiges Problem, wenn mehrere VMs mit derselben Datenbank mit separaten Caches ausgeführt werden. Es heißt "Cache Drift".

Die meisten hibernate-freundlichen Cache-Implementierungen (ehcache, OSCache und SwarmCache) verfügen über einen integrierten integrierten Cache, der zum Synchronisieren der Caches verwendet werden kann. Der verteilte Cache sendet im Allgemeinen Multicast-Nachrichten, die den Zustand des Cache aktualisieren. Eine Cache-Räumung auf der zweiten Ebene beispielsweise durch SessionFactory.evict (Class, ID) bewirkt, dass eine Ungültigkeitsnachricht an die anderen Caches im Cluster gesendet wird, wodurch alle anderen Kopien dieses Objekts in anderen Caches ungültig werden.

Abhängig von Ihrer Bereitstellung kann das Multicast für Sie akzeptabel sein oder auch nicht. Wenn dies nicht der Fall ist, müssen Sie möglicherweise eine Single-Cache-Lösung wie Memcached verwenden.

Ich persönlich fand die Konfiguration des verteilten Cachespeichers sehr einfach.

EH-Cache diskutiert das Problem hier ein wenig genauer: Ссылка

    
StevenWilkins 16.11.2010 17:03
quelle