2009-12-28 6 views
6

erlebe ich die folgende offenbar nicht dokumentierte Problem, und ich möchte, wennHibernate Second-Level-Cache-Objekte, die faul sind = false, führen zu einem Standard fetch = Join, ist es irgendwo dokumentiert?

  1. ich etwas falsch
  2. tat verstehen
  3. Hat jemand das gleiche Problem begegnen?
  4. Ist es wirklich nirgendwo dokumentiert? oder habe ich etwas vermisst?

Das Verhalten dieses die folgende Zuordnung

<class name="org.sample.Foo" table="foo"> 
    ... 
    <many-to-one name="bar" class="org.sample.Bar"/> 
</class> 


<class name="org.sample.Bar" table="bar" lazy="false"> 
    ... 
</class> 

Zuerst als Hintergrund sei angenommen ist, den Standardwert Ruhezustand für das Attribut auf einem zu-Eins-viele-Beziehung holen sollte "wählen ", das ist zumindest, was dokumentiert ist (ich werde den Link hier hinzufügen, wenn ich es finde)

Dies ist jedoch nur wahr, wenn die referenzierte Klasse faul ist =" wahr "!

so offenbar die obige Abbildung in dieser übersetzt wird (weil Bar faul = "false"):

<class name="org.sample.Foo" table="foo"> 
    ... 
    <many-to-one name="bar" class="org.sample.Bar" *fetch="join" /> 
</class> 


<class name="org.sample.Bar" table="bar" lazy="false"> 
    ... 
</class> 

Nun, warum das wäre ein Problem sein? anstelle von 2 wählt, Hibernate wird die nicht faule Referenz in einer einzigen Auswahl mit seiner "Eltern" laden (Laden Foo mit Bar in einem einzigen Auswahl)

Dies macht eigentlich Sinn, da das Objekt nicht faul ist, warum nicht laden es?

Die Antwort ist dies: Was passiert, wenn Bar in der 2. Ebene Cache ist?

<class name="org.sample.Foo" table="foo"> 
    ... 
    <many-to-one name="bar" class="org.sample.Bar" *fetch="join" /> 
</class> 


<class name="org.sample.Bar" table="bar" lazy="false"> 
    <cache usage="transactional" /> 
    ... 
</class> 

Und die Antwort ist - nichts ändert sich!

Angenommen, Hibernate ist intelligent genug, um zu verstehen, dass Objekte dieses Typs nicht geladen werden sollten, aber da der standardmäßige Abruf von Auswahl zu Verknüpfung geändert wurde, hat Hibernate keine Wahl reale Tabelle mit der zweiten Level-Cache, noch)

so tut Hibernate, was es erzählt wird, und verwendet eine Verknüpfung ein Objekt aus der Datenbank zu holen, wo es

die Lösung fand ich bereits im 2. Level-Cache ist ist, das Mapping buchstäblich zu fetch = "select" zu ändern

Jetzt wenn die zweite Auswahl für Bar ist im Begriff zu gehen, versteht Hibernate es sollte nicht in die Datenbank gehen, und holt es aus dem Cache. und nur 1 Abfrage wird ausgeführt (nach dem Warmup)

+0

Das Abrufverhalten hängt von der API ab, die Sie zum Abfragen der Objekte verwenden. Verwenden Sie die HQL- oder Kriterien-API? – skaffman

+0

Weder eine einfache session.load (Foo.class, id) –

Antwort

4

Ich stieß auf das gleiche Problem, und fand mich markieren alle Viele-zu-eins-Beziehungen, die als fetch="select" zwischengespeichert werden. Zu dem Zeitpunkt, zu dem die Abfrage aufgebaut wird, kann Hibernate nicht wissen, ob die angeforderte Instanz von Bar im Cache der zweiten Ebene ist oder nicht (unter der Annahme, dass Foo nicht zwischengespeichert ist).

+0

Aber ist es nicht seltsam, es ist nicht dokumentiert, nicht einmal in den offiziellen kommerziellen Bücher?Sogar in Foren oder hier in SO fand ich keine Erwähnung dieses Problems ... –

+0

Ich stimme zu. Aber um zu verstehen, was Winterschlaf genau macht, muss ich oft SQL-Logging durchführen und schauen, was gerade passiert. – bertolami