【问题标题】:HQL to retrieve list of distinct entities in many to one relationshipHQL 检索多对一关系中不同实体的列表
【发布时间】:2012-04-09 22:50:48
【问题描述】:

在我的应用程序中,用户可以生成对事物的请求,因此我有两个实体 Request 和 User 映射到同名的基础表。存在多对一关系,因此用户可以提出许多请求。因此,我的请求实体看起来像这样

@实体 @Table(name="请求") 公共类请求实现可序列化{ 私人 int id; 私人用户请求者; @ID @Column(name="ID", unique=true, nullable=false) 公共 int getId() { 返回这个.id; } @ManyToOne(fetch=FetchType.EAGER) @JoinColumn(name="REQUESTER", nullable=false) 公共用户 getRequester() { 返回 this.requester; } }

我需要获取至少提出一个请求的所有用户的列表。

我尝试了以下方法:

公共列表retrieveAllRequesters(){ return hbSession().createQuery("select requester from Request r left join r.requester as requester").list(); }

但这会为每个请求返回一个实体

我尝试像这样添加 distinct 关键字:

从 Request r 中选择不同的请求者 left join r.requester as requester

但这会导致 HQL 语法错误

我尝试了很多其他方法,将 left 连接更改为 innerouter,但没有成功。

我很感激 HQL 能做我需要做的事情的建议。谢谢。

Bohemian 建议这可能是方言问题,所以我启用了 hibernate.show_sql 并显示以下内容:

休眠: 选择 不同的 user1_.ID 为 ID10_, user1_.EMAIL_ADDRESS 作为 EMAIL2_10_, user1_.EXTERNAL_ID 为 EXTERNAL3_10_, user1_.IS_ADMINISTRATOR 作为 IS4_10_, user1_.IS_SUPERVISOR 为 IS5_10_, user1_.IS_TECHNICIAN 作为 IS6_10_, user1_.LAST_CHECKED_IN_AT 作为 LAST7_10_, user1_.LAST_LOGGED_IN_AT 作为 LAST8_10_, user1_.LAST_UPDATED_AT 作为 LAST9_10_, user1_.NAME 作为 NAME10_, user1_.UI_PREFERENCES 作为 UI11_10_ 从 请求请求0_ 内部联接 [用户] user1_ 在 request0_.REQUESTER=user1_.ID 2255 [main] WARN org.hibernate.util.JDBCExceptionReporter - SQL 错误:421,SQLState:S0001 2255 [main] 错误 org.hibernate.util.JDBCExceptionReporter - 文本数据类型无法选择为 DISTINCT,因为它不可比较。

数据库是 MS SQL Server。

【问题讨论】:

    标签: hibernate hql many-to-one


    【解决方案1】:

    使用 HQL,您不需要“加入” - 它已经隐式加入。试试这个:

    return hbSession()
       .createQuery("select distinct r.requester from Request r")
       .list();
    

    已编辑

    从最近补充的问题来看,重点是:

    The text data type cannot be selected as DISTINCT because it is not comparable
    

    这似乎是来自 microsoft *sigh* 的又一点蹩脚代码(我曾经使用过的每个数据库都可以处理它 - 这只是我从未使用过 MS SQL 的另一个原因)

    您必须将 text 列的数据类型更改为 varchar(something),在它们上使用 substring(1, n)(在 HQL 中)以将它们缩短为某种东西可怜的 MS SQL 可以“比较”

    【讨论】:

    • 谢谢。我刚刚尝试过,但我得到了添加 distinct 关键字时得到的 SQLGrammarException。如果我删除 distinct 则不会出现异常,但随后我会为每个请求获得一行
    • 应该可以(过去对我有用)。听起来像一个错误或方言不匹配。你用的是什么数据库,什么方言?
    • MS-Sql Server(最新版本)方言是org.hibernate.dialect.SQLServerDialect
    • 只要requestor 是单个对象(不是集合等),这应该可以工作。除了“祝你好运”,我不知道还能说什么
    • 我已启用 hibernate.show_sql,它显示了一些我将添加到我的问题中的更多信息
    【解决方案2】:

    非常感谢 Bohemian 为我指明了正确的方向。他的出色回答值得更多投票。

    是的,这是 MS SQL Server 的一个限制,特别是它无法处理具有 distinct 的“文本”字段,但更多的是我不明白 distinct 将比较它返回的实体中的所有字段,而不仅仅是 ID 字段。

    因此,我的答案是重新配置我的 HQL,以便它只返回我感兴趣的字段,而不是整个用户实体。这是它现在的样子:

    公共列表检索所有请求者(){ return hbSession().createQuery("select distinct r.requester.id, r.requester.name from Request r").list(); }

    【讨论】:

      猜你喜欢
      • 2016-06-03
      • 1970-01-01
      • 2021-11-17
      • 2015-03-06
      • 1970-01-01
      • 2016-09-01
      • 2016-08-24
      • 1970-01-01
      • 2016-07-23
      相关资源
      最近更新 更多