【问题标题】:One-to-many with criteria带标准的一对多
【发布时间】:2010-11-10 07:49:17
【问题描述】:

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

知道如何在项目列表上应用标准吗?

【问题讨论】:

    标签: hibernate criteria one-to-many


    【解决方案1】:

    您有两种选择:
    A) 您可以在MyClass"items" 集合上定义一个过滤器:

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

    然后你可以通过调用来应用它

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

    在检索您的对象之前。在这种情况下,您将只指定基于MyClass 的标准,而不是基于Item(如果您需要标准,如​​果您只需要id,则可以使用session.load())。

    B) 将您的 items 集合设置为延迟获取。查询(或通过 id 检索)您的 MyClass 对象,然后仅基于 Item 创建条件(不链接到 MyClass):

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

    这将返回Items 的列表(从您的映射来看,无论如何都没有返回MyClass 的链接)。选项 (B) 将生成您正在寻找的 SQL 查询。

    【讨论】:

      【解决方案2】:
      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 执行相同的操作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-14
        • 2014-01-28
        • 1970-01-01
        相关资源
        最近更新 更多