Hibernate HQL检索多对一关系中不同实体的列表

Hibernate HQL检索多对一关系中不同实体的列表,hibernate,hql,many-to-one,Hibernate,Hql,Many To One,在我的应用程序中,用户可以生成对事物的请求,因此我有两个实体请求和用户映射到同名的底层表。存在多对一关系,因此用户可以发出多个请求。因此,我的请求实体如下所示 @Entity @Table(name="request") public class Request implements Serializable { private int id; private User requester; @Id @Column

在我的应用程序中,用户可以生成对事物的请求,因此我有两个实体请求和用户映射到同名的底层表。存在多对一关系,因此用户可以发出多个请求。因此,我的请求实体如下所示

@Entity @Table(name="request") public class Request implements Serializable { private int id; private User requester; @Id @Column(name="ID", unique=true, nullable=false) public int getId() { return this.id; } @ManyToOne(fetch=FetchType.EAGER) @JoinColumn(name="REQUESTER", nullable=false) public User getRequester() { return this.requester; } } @实体 @表(name=“请求”) 公共类请求实现可序列化{ 私有int-id; 私人用户请求者; @身份证 @列(name=“ID”,unique=true,nullable=false) 公共int getId(){ 返回此.id; } @manytone(fetch=FetchType.EAGER) @JoinColumn(name=“REQUESTER”,nullable=false) 公共用户getRequester(){ 返回此.requester; } } 我需要获得至少发出一个请求的所有用户的列表

我尝试了以下方法:

public List<User> retrieveAllRequesters() { return hbSession().createQuery("select requester from Request r left join r.requester as requester").list(); } Hibernate: select distinct user1_.ID as ID10_, user1_.EMAIL_ADDRESS as EMAIL2_10_, user1_.EXTERNAL_ID as EXTERNAL3_10_, user1_.IS_ADMINISTRATOR as IS4_10_, user1_.IS_SUPERVISOR as IS5_10_, user1_.IS_TECHNICIAN as IS6_10_, user1_.LAST_CHECKED_IN_AT as LAST7_10_, user1_.LAST_LOGGED_IN_AT as LAST8_10_, user1_.LAST_UPDATED_AT as LAST9_10_, user1_.NAME as NAME10_, user1_.UI_PREFERENCES as UI11_10_ from request request0_ inner join [user] user1_ on request0_.REQUESTER=user1_.ID 2255 [main] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 421, SQLState: S0001 2255 [main] ERROR org.hibernate.util.JDBCExceptionReporter - The text data type cannot be selected as DISTINCT because it is not comparable. 公共列表检索AllRequesters(){ return hbSession().createQuery(“从请求中选择请求者,r向左加入r.requester作为请求者”).list(); } 但这会为每个请求返回一个实体

我尝试添加distinct关键字,如下所示:

select distinct requester from Request r left join r.requester as requester 从请求r中选择不同的请求者left join r.requester作为请求者 但这导致了HQL语法错误

我尝试了很多其他的方法,将连接更改为内部外部,但没有成功

如果能给我一个建议,让HQL做我需要的事情,我将不胜感激。谢谢


Bohemian认为这可能是一个方言问题,因此我启用了hibernate.show_sql,它显示了以下内容:

public List<User> retrieveAllRequesters() { return hbSession().createQuery("select requester from Request r left join r.requester as requester").list(); } Hibernate: select distinct user1_.ID as ID10_, user1_.EMAIL_ADDRESS as EMAIL2_10_, user1_.EXTERNAL_ID as EXTERNAL3_10_, user1_.IS_ADMINISTRATOR as IS4_10_, user1_.IS_SUPERVISOR as IS5_10_, user1_.IS_TECHNICIAN as IS6_10_, user1_.LAST_CHECKED_IN_AT as LAST7_10_, user1_.LAST_LOGGED_IN_AT as LAST8_10_, user1_.LAST_UPDATED_AT as LAST9_10_, user1_.NAME as NAME10_, user1_.UI_PREFERENCES as UI11_10_ from request request0_ inner join [user] user1_ on request0_.REQUESTER=user1_.ID 2255 [main] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 421, SQLState: S0001 2255 [main] ERROR org.hibernate.util.JDBCExceptionReporter - The text data type cannot be selected as DISTINCT because it is not comparable. 冬眠: 选择 不同的user1.ID作为ID10, 用户1。电子邮件地址为EMAIL2\u 10\u, user1.EXTERNAL\u ID作为EXTERNAL3\u 10\u, user1是IS4\u 10\u的管理员, 用户1是IS5的ISU主管, 用户1是IS6的技术员, 用户1。最后一次登记为最后7次登记为最后10次登记, 用户1上次登录时间为最后8次10次, 用户1。上次更新时间为最后9\u 10\u, user1_u2;名称为NAME10_2;, user1\u.UI\u首选项为UI11\u 10\u 从…起 请求0_ 内连接 [用户]用户1\u 在请求0时,请求者=用户1 2255[main]WARN org.hibernate.util.jdbceptionReporter-SQL错误:421,SQLState:S0001 2255[main]ERROR org.hibernate.util.jdbceptionReporter-无法将文本数据类型选择为独立的,因为它不可比较。
数据库是MS SQL Server。

使用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
这似乎又是一段来自微软的蹩脚代码(我使用过的每一个数据库都能处理它——这只是我从未使用MS SQL的另一个原因)


您必须将
text
列的数据类型更改为varchar(something),或者在其上使用
子字符串(1,n)
(在HQL中)将其缩短为可怜的MS SQL可以“比较”的数据类型。多亏Bohemian为我指明了正确的方向。他出色的回答值得更多的投票支持

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

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

public List<Object[]> retrieveAllRequesters() { return hbSession().createQuery("select distinct r.requester.id, r.requester.name from Request r").list(); } 公共列表检索AllRequesters(){ 返回hbSession().createQuery(“从请求r中选择不同的r.requester.id、r.requester.name”).list(); }
谢谢我只是尝试了一下,但是我得到了SQLGrammarException,这是我在添加distinct关键字时得到的。如果我删除distinct,我不会得到异常,但是我会为每个应该工作的请求得到一行(它在过去对我有效)。听起来像是错误或方言不匹配。您使用的是什么数据库和什么方言?MS Sql Server(最新版本)方言是org.hibernate.dialogue.sqlserverdialogue只要
请求者
是单个对象(不是集合等),这应该可以工作。除了“祝你好运”之外,我不知道还有什么要说,我已经启用了hibernate.show_sql,它显示了我将添加到我的问题中的更多信息