简体   繁体   English

一对多的条件

[英]One-to-many with criteria

enter code here I want to apply restrictions on the list of items, so only items from a given dates will be retrieved. enter code here我想对项目列表应用限制,因此将只检索给定日期的项目。

Here are my mappings: 这是我的映射:

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

I tried this code: 我尝试了这段代码:

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

which result the following quires: 结果导致以下需求:

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

followed by 其次是

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

But what I need is something like: 但是我需要的是这样的:

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

followed by 其次是

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

Any idea how I can apply a criteria on the list of items? 知道如何在项目列表中应用条件吗?

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

Just be aware that you are creating a "live" filtered view of that collection. 请注意,您正在创建该集合的“实时”筛选视图。 If you see cases where all the other Items that should be part of that collection start getting deleted you know exactly where to look. 如果您发现本应作为该集合一部分的所有其他项目开始被删除的情况,则您确切地知道要查找的位置。

Your much better bet is to just query for the list of Items you want directly: 更好的选择是直接查询您想要的项目列表:

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

You can do the same with Criteria using projections. 您可以使用投影对条件进行相同的处理。

You have two options here: 您在这里有两个选择:
A) You can define a filter on "items" collection of MyClass : A)您可以在MyClass "items"集合上定义过滤器:

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

You would then apply it by calling 然后,您可以通过致电应用

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

prior to retrieving your object. 在检索对象之前。 In this scenario you would only specify Criteria based on MyClass , not on Item (if you need Criteria at all, you can just use session.load() if all you need is id ). 在这种情况下,您将仅基于MyClass而不是基于Item指定Criteria(如果您完全需要Criteria,则仅在需要id时才可以使用session.load() )。

B) Set your items collection to lazy fetch. B)将您的items集合设置为延迟获取。 Query (or retrieve by id) your MyClass object, then create criteria based on Item alone (without linking to MyClass ): 查询(或按ID检索) MyClass对象,然后仅基于Item创建条件(不链接到MyClass ):

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

This would return a list of Items (which, judging from your mapping don't have a link back to MyClass anyway). 这将返回一个Items列表(从映射中判断,该链接MyClass没有指向MyClass的链接)。 Option (B) would produce the SQL queries you're looking for. 选项(B)将产生您要查找的SQL查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM