2009-07-13 3 views
0

enter code here Ich möchte Beschränkungen für die Liste der Elemente anwenden, so dass nur Elemente aus einem bestimmten Datum abgerufen werden.Eins-zu-viele mit Kriterien

Hier sind meine Zuordnungen:

<class name="MyClass" 
      table="MyTable" mutable="false" > 
      <cache usage="read-only"/> 
    <id name="myId" column="myId" type="integer"/> 
    <property name="myProp" type="string" column="prop"/> 
    <list name="items" inverse="true" cascade="none"> 
     <key column="myId"/> 
     <list-index column="itemVersion"/> 
     <one-to-many class="Item"/> 
    </list> 
    </class> 
    <class name="Item" 
      table="Items" mutable="false" > 
      <cache usage="read-only"/> 
    <id name="myId" column="myId" type="integer"/> 
    <property name="itemVersion" type="string" column="version"/> 
    <property name="startDate" type="date" column="startDate"/> 
    </class> 

ich diesen Code versucht:

Criteria crit = session.createCriteria(MyClass.class); 
crit.add(Restrictions.eq("myId", new Integer(1))); 
crit = crit.createCriteria("items").add(Restrictions.le("startDate", new Date())); 

, die folgende dert führen:

select ... 
from MyTable this_ inner join Items items1_ on this_.myId=items1_.myId 
where this_.myId=? and items1_.startDate<=? 

gefolgt von

select ... 
from Items items0_ 
where items0_.myId=? 

Aber was ich brauche, ist so etwas wie:

select ... 
from MyTable this_ 
where this_.myId=? 

von

gefolgt
select ... 
from Items items0_ 
where items0_.myId=? and items0_.startDate<=? 

Jede Idee, wie ich ein Kriterium auf der Liste der Elemente anwenden kann?

Antwort

0

Sie haben zwei Möglichkeiten:
A) Sie können einen Filter auf "items" Sammlung von MyClass definieren:

<filter name="starDateFilter" condition="startDate <= :startDate"/> 

würden Sie dann anwenden, indem

session.enableFilter("startDateFilter").setParameter("startDate", new Date()); 

vor dem Abrufen Aufruf Ihrer Objekt. In diesem Szenario würden Sie nur Kriterien basierend auf MyClass und nicht auf Item angeben (wenn Sie Kriterien überhaupt benötigen, können Sie einfach session.load() verwenden, wenn Sie nur id benötigen).

B) Stellen Sie Ihre items Sammlung auf Lazy Fetch ein. Query (oder Abrufen von id) Ihr MyClass Objekt, dann Kriterien auf Item allein auf Basis schaffen (ohne Anbindung an MyClass):

Criteria crit = session.createCriteria(Item.class); 
crit.add(Restrictions.le("startDate", new Date())); 

Dies würde eine Liste von Items (die von Ihrem Mapping zu urteilen nicht über ein Link zurück zu MyClass sowieso). Option (B) würde die SQL-Abfragen erzeugen, nach denen Sie suchen.

0
Criteria crit = session.createCriteria(MyClass.class); 
crit.add(Restrictions.eq("myId", new Integer(1))); 
crit.setFetchMode("items", FetchMode#JOIN); 
crit = crit.createCriteria("items").add(Restrictions.le("startDate", new Date())); 

Beachten Sie, dass Sie eine "live" gefilterte Ansicht dieser Sammlung erstellen. Wenn Sie Fälle sehen, in denen alle anderen Elemente, die Teil dieser Sammlung sein sollten, gelöscht werden, wissen Sie genau, wo Sie suchen müssen.

Ihre viel bessere Wette ist die Abfrage nur für die Liste der Elemente, die Sie direkt möchten:

String hql = "select i from MyClass m inner join m.items i where i.startDate <= :theDate"; 
List items = session.createQuery(hql) 
     .setParameter("theDate", theDate) 
     .list(); 

Sie können unter Verwendung von Projektionen mit Kriterien das gleiche tun.