Wie prüfen, ob Hibernate Collection initialisiert?

Status
Nicht offen für weitere Antworten.

byte

Top Contributor
Hallo,

ich teste meine DAOs via @TransactionConfiguration(defaultRollback = true), was auch soweit gut klappt. Nun habe ich mir einen Mechanismus geschrieben, der bestimmte Teile des Objektgraphen automatisch per Join oder Select vorlädt. Ich möchte diesen Mechanismus nun gerne unittesten, weiss jedoch nicht so genau wie. Um zu prüfen, welche Daten im Objektgraph schon geladen sind und welche nicht (als noch lazy sind), müsste ich die Transaktion schließen. Das funktioniert dann natürlich nicht mehr mit dem defaultRollback = true. Besser wäre also, die Transaktion zu suspenden. Leider weiss ich nicht, ob und wie das möglich ist. Meine Unittests erben von AbstractTransactionalTestNGSpringContextTests. Ich habe versucht, in meiner Testklasse eine Methode mit @Transactional(propagation = Propagation.NOT_SUPPORTED) zu deklarieren und in dieser Methode das Property aufzurufen. Aber offenbar werden diese Annotations in den Unittests ignoriert.

Gibts vielleicht noch eine andere Möglichkeit, bei Hibernate-Objekten zu prüfen, ob ein Property geladen oder noch lazy ist?

Wäre über Anregungen dankbar.

TIA byto
 

byte

Top Contributor
Ich habe es nun mit Hibernate.isInitialized(proxy) versucht, aber irgendwie scheint die Methode immer true zurückzuliefern, wenn die Hibernate Session noch offen ist. Wenn ich das Objekt hingegen zum Client weiterreiche (die Session ist dann geschlossen), liefert die Methode false (was dem gewünschten Verhalten entspricht). ???:L
 

KSG9|sebastian

Top Contributor
Hi,

Problem ist dass Hibernate.isInitialized für Collections immer "true" zurückgibt.
API-Doc: "...true if the argument is already initialized, or is not a proxy or collection.."

Die Methode liefert nur false wenn das Objekt ein Proxy ist. Im Javamagazin wurde das auch mal beschrieben (glaub für so n Preload-Pattern). Leider funktioniert das ganze nicht für Collections, da die immer "initialisiert" sind.

Du kannst prüfen ob die Elemente in der Collection ein Proxy (und somit lazy) sind. Das könte funktionieren.
Eine gute Möglichkeit um festzustellen ob das Objekt schon geladen ist oder nicht habe ich leider auch noch nicht gefunden. Abfragen auf isInstance o.ä. sind zwar machbar, allerdings auch sehr, sehr unschön
 
M

maki

Gast
>> Gibts vielleicht noch eine andere Möglichkeit, bei Hibernate-Objekten zu prüfen, ob ein Property geladen oder noch lazy ist?

Da fällt mir eben nur die Sache mit der geschlossenen Session ein, dann weiss man ganz schnell ob es lazy war oder nicht *g*

Alledings würde so ein Unittest schnell zum Integrationstest mutieren, wenn dir das nix ausmacht, wäre das zB ein Weg.
 

byte

Top Contributor
Du kannst prüfen ob die Elemente in der Collection ein Proxy (und somit lazy) sind. Das könte funktionieren.
Das ist doch genau der Punkt. Wie prüfe ich das? Ich habe z.B. eine PersistentList, dessen Elemente noch nicht geladen sind. Die PersistentList ist ja ein Proxy, der bei Bedarf lazy die eigentliche Collection lädt. Ist nun noch eine Session an die PersistentList gebunden, dann liefert Hibernate.isInitialized() true, obwohl das Feld initialized false ist (sieht man im Debugger). Detached man die Collection (die Session der PersistentList ist null), dann liefert Hibernate.isInitialized() false.

Abfragen auf isInstance o.ä. sind zwar machbar, allerdings auch sehr, sehr unschön
Verstehe nicht, wie mir das helfen soll? Die Collection ist immer eine PersistentList, egal ob attached oder detached, egal ob initialisiert oder nicht.

Ich sehe derzeit nur die Möglichkeit, per Reflection das private Feld initialized zu überprüfen, aber das ist ja ne Brechstangenmethode.
 

KSG9|sebastian

Top Contributor
Ich meinte für jedes Element in der Collection Hibernate.isInitialized aufrufen

Code:
Query qry = em.createQuery("from Person p where p.id=1");
Person pers = qry.getSingleResult();
for(Account acc : pers.getAccounts){
   if(Hibernate.isInitialized(acc)){
       // collection element ist kein proxy
   }
}

- Collections sind immer initialisiert
- Objekte sind dann initialisiert wenn sie kein Proxy mehr sind

Falls das nicht passt ist es evtl. ein Bug in Hibernate. Welche Hibernate-Version verwendest du denn?
 

byte

Top Contributor
Also nochmal: Es geht mir darum bei offener Session zu prüfen, ob die Elemente einer Collection schon geladen wurden. Dein Tipp macht keinen Sinn, denn wenn ich auf die Elemente der Collection zugreife, um sie per Hibernate.isInitialized() zu überprüfen, dann werden sie ja geladen.
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben