符合标准的一对多

时间:2009-07-13 14:31:16

标签: hibernate criteria one-to-many

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 :(得分:0)

这里有两个选择:
A)您可以在"items"的{​​{1}}集合上定义过滤器:

MyClass

然后您可以通过调用

来应用它
<filter name="starDateFilter" condition="startDate <= :startDate"/>

在检索对象之前。在这种情况下,您只需根据session.enableFilter("startDateFilter").setParameter("startDate", new Date()); 指定条件,而不是MyClass(如果您需要条件,如果您需要的是Item,则可以使用session.load() )。

B)将您的id集合设置为延迟抓取。查询(或按ID检索)您的items对象,然后单独根据MyClass创建条件(不链接到Item):

MyClass

这将返回Criteria crit = session.createCriteria(Item.class); crit.add( Restrictions.le("startDate", new Date()) ); 的列表(根据您的映射判断,无论如何都没有返回Items的链接)。选项(B)将生成您正在寻找的SQL查询。

答案 1 :(得分: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()) );

请注意,您正在创建该集合的“实时”过滤视图。如果您看到应该属于该集合的所有其他项目开始被删除的情况,您就会知道确切的位置。

更好的选择是直接查询您想要的项目列表:

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

您可以使用投影对Criteria执行相同的操作。