当前位置: 首页 > 面试题库 >

使用Max()投影在关键字段上并按外键主键进行休眠条件查询

桓宜
2023-03-14
问题内容

我在Hibernate(版本3.2.5)中很难将此查询(可直接在数据库上使用)表示为条件查询:

SELECT s.* 
  FROM ftp_status s 
 WHERE (s.datetime,s.connectionid) IN (SELECT MAX(f.datetime),
                                              f.connectionid 
                                         FROM ftp_status f
                                        GROUP BY f.connectionid);

到目前为止,这是我要解决的问题,它不起作用,并引发could not resolve property: datetime of: common.entity.FtpStatus错误消息:

Criteria crit = s.createCriteria(FtpStatus.class);
crit = crit.createAlias("connections", "c");
crit = crit.createAlias("id", "f");
ProjectionList proj = Projections.projectionList();
proj = proj.add(Projections.max("f.datetime"));
proj = proj.add(Projections.groupProperty("c.connectionid"));
crit = crit.setProjection(proj);
List<FtpStatus> dtlList = crit.list();

这是Netbeans 6.8直接从数据库生成的相关参考配置:

FtpStatus.hbm.xml-

<hibernate-mapping>
   <class name="common.entity.FtpStatus" table="ftp_status" catalog="common">
        <composite-id name="id" class="common.entity.FtpStatusId">
            <key-property name="siteid" type="int">
                <column name="siteid" />
            </key-property>
            <key-property name="connectionid" type="int">
                <column name="connectionid" />
            </key-property>
            <key-property name="datetime" type="timestamp">
                <column name="datetime" length="19" />
            </key-property>
        </composite-id>
        <many-to-one name="connections" class="common.entity.Connections" update="false" insert="false" fetch="select">
            <column name="connectionid" not-null="true" />
        </many-to-one>
        <many-to-one name="sites" class="common.entity.Sites" update="false" insert="false" fetch="select">
            <column name="siteid" not-null="true" />
        </many-to-one>
        <property name="upInd" type="boolean">
            <column name="up_ind" not-null="true" />
        </property>
        <property name="lastMessage" type="string">
            <column name="last_message" length="65535" not-null="true" />
        </property>
    </class>
</hibernate-mapping>

Connections.hbm.xml-

<hibernate-mapping>
    <class name="common.entity.Connections" table="connections" catalog="common">
        <id name="connectionid" type="java.lang.Integer">
            <column name="connectionid" />
            <generator class="identity" />
        </id>
        <property name="ip" type="string">
            <column name="ip" length="15" not-null="true" />
        </property>
        <property name="port" type="int">
            <column name="port" not-null="true" />
        </property>
        <property name="user" type="string">
            <column name="user" length="8" not-null="true" />
        </property>
        <property name="password" type="string">
            <column name="password" length="50" not-null="true" />
        </property>
        <set name="ftpStatuses" inverse="true">
            <key>
                <column name="connectionid" not-null="true" />
            </key>
            <one-to-many class="common.entity.FtpStatus" />
        </set>
    </class>
</hibernate-mapping>

我知道我丢失了一些东西,但是我对hibernate状态的谷歌搜索还没有发现它。或者,直接使用s.createSQLQuery()或进行SQL查询s.createQuery()也是可以接受的,但是编写该查询的成功率甚至更低。


问题答案:

Criteria您提供的似乎只产生内部查询部分。您可以组合内部查询,例如通过使用DetachedCriteria

DetachedCriteria maxDateQuery = DetachedCriteria.forClass(FtpStatus.class);
ProjectionList proj = Projections.projectionList();
proj.add(Projections.max("datetime"));
proj.add(Projections.groupProperty("connectionid"));
maxDateQuery.setProjection(proj);

Criteria crit = s.createCriteria(FtpStatus.class);
crit.add(Subqueries.propertiesEq(new String[] {"datetime", "connectionid"}, maxDateQuery));

List<FtpStatus> dtlList = crit.list();

请注意,直到Hibernate
4.0.0.CR5(HHH-6766)
才实现对多列子查询的支持。

对于本机SQL查询,createSQLString如果希望在结果查询中使用显式列名,则Hibernate
可以直接使用您指定的查询字符串或添加的查询所涉及的实体。

String queryString = "SELECT {status.*}"
                   + "  FROM ftp_status status"
                   + "  WHERE (datetime, connectionid) IN ("
                   + "    SELECT MAX(datetime), connectionid"
                   + "      FROM ftp_status"
                   + "      GROUP BY connectionid"
                   + "  )";

SQLQuery query = s.createSQLQuery(queryString).addEntity("status", FtpStatus.class);

List<FtpStatus> dtlList = query.list();


 类似资料:
  • 问题内容: 我必须与Hibernate合作,但我不确定如何解决此问题,我有2个具有1..n关系的表,如下所示: 如何使用Hibernate进行管理? 我不知道如何声明将包含主键一部分的外键。 我的数据库架构是从Hibernate模型生成的。 问题答案: 我找到了解决此问题的两种方法。 第一个是一种解决方法,没有第二个那么整洁。 将实体的主键定义为包含,和的复合键,首先将假定为主键的内容定义为唯一约

  • 问题内容: 我使用Hibernate制作了一个示例应用程序。我的要求是表上没有主键。我只需要从应用程序中选择查询。我知道应该有一个主键,但是我所引用的表没有它。 它有大约5万条记录。因此,修改表以添加ID列将看不到可行的选项。 有可能吗 问题答案: Hibernate 要求 实体表具有主键。故事结局。 在谈论数据库时,5万条记录根本就不多。 我的建议:在表中添加一个自动增量整数PK列。您会对它的速

  • 问题内容: 我使用spring数据并hibernate@ Filter / @ FilterDef来过滤软删除的实体。似乎springRepository.findOne(id)总是返回值,即使id被软删除。此方法以及通过外键搜索其他字段的where子句中不包含过滤器。在这种情况下是否可以启用过滤器,使其可以用作@Where注释? 问题答案: 我有同样的问题。我已经通过实现HibernatePer

  • 我对DynamoDB非常陌生(一般没有Sql),在理解如何形成一个简单的查询时遇到了一些困难。。 我想在SQL中执行一个简单的选择,但似乎无法完成。 我的表定义基本上是: 表名snsNotiations主分区密钥接收者ID(编号) 它遵循一些属性(如readAt)。 我要执行的查询是: 我甚至可以在AWS UI上执行此查询:截图 我的lambda函数使用以下内容: 但我得到以下错误: 无法查询。错

  • 问题内容: 目前,Hibernate允许我直接使用*对一关系定义的对象 是否可以获取外键而不是对象? 我看到的当前方法是在映射中添加addint: 是否有更好的方法来获取外键,或者这是唯一的方法? 问题答案: 是的,你可以这样做。您只需要清楚地告诉休眠状态,哪一个是应该维护的映射,如下所示:

  • 问题内容: 简而言之:hibernate状态不支持投影和示例查询吗?我发现了这篇文章: 代码是这样的: 就像其他张贴者所说的那样,生成的sql始终具有一个where类,仅 引用y0_ =? 而不是this_.city。 我已经尝试了几种方法,并搜索了问题跟踪器,但对此一无所获。 我什至尝试使用Projection别名和Transformers,但是它不起作用: 有没有人通过示例使用投影和查询? 问