Один ко многим с критериями - PullRequest
0 голосов
/ 13 июля 2009

enter code here Я хочу применить ограничения к списку предметов, поэтому будут извлечены только предметы с заданными датами.

Вот мои отображения:

    <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>

Я попробовал этот код:

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

, в результате чего получаются следующие запросы:

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

с последующим

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

Но мне нужно что-то вроде:

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

с последующим

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

Есть идеи, как применить критерий в списке предметов?

Ответы [ 2 ]

0 голосов
/ 23 мая 2012
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()) );

Просто имейте в виду, что вы создаете «живое» фильтрованное представление этой коллекции. Если вы видите случаи, когда все другие Предметы, которые должны быть частью этой коллекции, начинают удаляться, вы точно знаете, где искать.

Ваша гораздо лучшая ставка - просто запросить список предметов, которые вы хотите напрямую:

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();

Вы можете сделать то же самое с критериями, используя проекции.

0 голосов
/ 13 июля 2009

У вас есть два варианта:
A) Вы можете определить фильтр для "items" коллекции MyClass:

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

Затем вы примените его, позвонив по номеру

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

до получения вашего объекта. В этом сценарии вы должны указывать критерии только на основе MyClass, а не Item (если вам вообще нужны критерии, вы можете просто использовать session.load(), если вам нужно только id).

B) Установите для своей коллекции items ленивую выборку. Запрос (или получение по id) вашего объекта MyClass, затем создание критериев на основе только Item (без ссылки на MyClass):

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

Это вернет список Items (который, судя по вашему сопоставлению, в любом случае не имеет ссылки на MyClass). Опция (B) выдаст SQL-запросы, которые вы ищете.

...