hibernate如何从一对多关系中选择多方面

时间:2013-08-29 09:43:29

标签: java hibernate

大家。我使用Hibernate是全新的。

所以我在这里面对一个问题,我有一个如下的实体:

<class name="cn.edu.scau.librarica.dao.MessageSession" table="msg_session">
    <id name="msid" type="long" unsaved-value="null">
        <generator class="identity"/>
    </id>

    <list name="msgs" cascade="all">
        <key column="msid" 
            update="false" unique="true" not-null="true"/>
        <list-index column="list_index"/>
        <one-to-many class="Message" />
    </list>
</class>

现在我想要实现的是:

    select Message m where msid=# and m.t<## and m.t>###

我如何用Criteria代表它?
提前感谢您的关注和建议。


更新
作为答案指南之一,我已经明白复合元素是不可查询的,所以我做了一个两个一对多的地图(更改在上面) 现在我可以查询,但现在我发现了另一个问题:
如何使用外键来映射复合ID Message就是这样的地图:

<class name="Message">
    <composite-id>
         <generator class="foreign">
             <!-- What here??? -->
         </generator>
    </composite-id>
</class>

根据指示,一对多可能会使用set而不是list,因此我很难找到符合我需要的样本(因为应该订购消息)。
有什么建议?我还在寻找那个。 谢谢你的帮助。

2 个答案:

答案 0 :(得分:1)

您不能直接选择消息,因为它是组件而不是实体。组件没有独立的生命周期。它们不能单独查询,创建或删除,它们总是必须通过嵌入它们的实体进行访问(在您的情况下为MessageSession)。

要使其成为实体,表应具有自己的主键。在你的情况下,似乎并非如此。您将需要更改架构,以便与Message对应的表具有主键,并将映射更改为使用一对多而不是复合元素。

如果你不能这样做,你将不得不查询MessageSession并从中获取消息。

P.S:Hibernate非常复杂,我没有看到太多人只是在试图解决问题时就把它拿起来。如果你花一些时间研究基础概念(比仅仅映射和查询更重要),你更有可能成功。

答案 1 :(得分:0)

这是问题的作者。

经过几天的研究,我找到了以某种方式满足我的要求的方法。

映射Message

<class name="cn.edu.scau.librarica.dao.Message" table="message">
    <id name="id" type="long">
        <generator class="identity" />
    </id>

    <many-to-one name="ms" class="cn.edu.scau.librarica.dao.MessageSession" 
     column="msid" not-null="true" insert="false" update="false" />
    <property name="s" type="long" />
    <property name="t" type="timestamp" />
    <property name="m" type="string" />
</class>

映射MessageSession

<class name="cn.edu.scau.librarica.dao.MessageSession" table="msg_session">
    <id name="msid" type="long" unsaved-value="null">
        <generator class="identity"/>
    </id>

    <property name="latest" type="timestamp" />

    <list name="msgs" table="msg_session_msgs" cascade="all">
        <key column="msid" 
            update="false" not-null="true"/>
        <list-index column="list_index"/>
        <one-to-many class="cn.edu.scau.librarica.dao.Message" />
    </list>
</class>

其中,不重要的是被忽视了。

事情进展顺利,而我可以找到限制为“很多”或相反的“一”。就像这样:

        DetachedCriteria dc = DetachedCriteria.forClass(Message.class)
            .createCriteria("ms")
            .add(Restrictions.eq("msid", msid));

        if (after != null)
            dc.add(Restrictions.gt("t", after));

        if (before != null)
            dc.add(Restrictions.lt("t", before));

...可以在指定期间内从指定的Message搜索MessageSession

所以诀窍是对象不能被Criteria返回,除非将它们作为实体匹配。

在底层数据库中,它会有点多余,因为Message可以由(msid,list_index)唯一标识,所以我找到了一种方法来匹配&lt; -this作为{的主键{1}}。