2012-11-07 11 views
7

Ich muss eine große Hibernate DetachedCriteria Abfrage ändern, um einige zusätzliche Zuordnungen abzurufen.Eager fetching verschachteltes Objekt mit DetachedCriteria in Hibernate

Meine Objektdiagramm ähnelt die Struktur unten, ich will die Verkäufe holen mit jedem Auto verbunden:

<class name="Showroom" table="showroom"> 
    ... 
    <bag name="cars" lazy="false"> 
     <one-to-many class="Car" /> 
    </bag> 
    ... 
</class> 

<class name="Car" table="car"> 
    ... 
    <set name="sales" lazy="true"> 
     <one-to-many class="Sale" /> 
    </set> 
    ... 
</class> 

Was möchte ich tun, ist so etwas wie:

DetachedCriteria criteria = DetachedCriteria.forClass(Showroom.class); 
// ... Existing criteria query code ... 
criteria.setFetchMode("cars.sales", FetchMode.JOIN); 

Aber das associationPath Argument in setFetchMode scheint die Punktnotation zu ignorieren und ich bekomme eine LazyInitializationException:

verursacht durch: org.hibe rnate.LazyInitializationException: failed eine Sammlung von Rolle zu lazily initialisieren: Car.sales wurde keine Sitzung oder einer Sitzung

geschlossen

Ich habe die Suche um und so fand bis jetzt keine Beispiele oder Informationen. Die Hibernate documentation bietet keine Beispiele zum Abrufen von verschachtelten Assoziationen, und die Javadoc for setFetchMode scheint darauf hinzuweisen, dass meine Punktnotation Ansatz hätte funktionieren sollen ...

Jede Hilfe wäre willkommen.

Antwort

15
DetachedCriteria dc = DetachedCriteria.forClass(ShowRoom.class, "showRoom"); 
criteria.setFetchMode("showRoom.cars", FetchMode.JOIN); 
criteria.createAlias("showRoom.cars", "car", CriteriaSPecification.LEFT_JOIN); 
criteria.setFetchMode("car.sales", FetchMode.JOIN); 

Sie können Eigenschaften in einer Kriterienabfrage nicht verketten. Und selbst in einer HQL-Abfrage ist cars.sales ungültig, da sich cars auf eine Sammlung und nicht auf eine Instanz von Auto bezieht. Ein Join ist notwendig, um sich auf ein Auto in der Autosammlung beziehen zu können. Das ist, was der Anruf createAlias() tut. Das obige ist ähnlich wie

select showRoom from ShowRoom 
left join fetch showRoom.cars car 
left join fetch car.sales 
+0

Perfekt, danke für die Erklärung. Ich wusste nicht, dass createAlias ​​einen doppelten Zweck hatte, Joins und Feldaliase zu erstellen. – seanhodges