在我的应用程序中,用户可以生成对事物的请求,因此我有两个实体请求和用户映射到同名的基础表。存在多对一关系,使得用户可以发出许多请求。因此,我的请求实体看起来像这样
@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; } }
我需要获取至少发出一个请求的所有用户的列表。
我尝试了以下内容:
public List<User> retrieveAllRequesters() { return hbSession().createQuery("select requester from Request r left join r.requester as requester").list(); }
但是这会为每个请求返回一个实体
我尝试添加 distinct 关键字,如下所示:
select distinct requester from Request r left join r.requester as requester
但是这导致了HQL语法错误
我尝试了很多其他方法,将左连接更改为内部和外部,但没有成功。
我很欣赏HQL建议我做我需要的东西。感谢。
Bohemian建议这可能是一个方言问题,所以我启用了hibernate.show_sql,它显示如下:
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.
数据库是MS SQL Server。
答案 0 :(得分:3)
使用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
它似乎是微软*sigh*
的另一个蹩脚代码(我曾经使用的每个数据库都可以处理它 - 这只是我从未使用过MS SQL的另一个原因)
您必须将text
列的数据类型更改为varchar(某物),或将substring(1, n)
更改为(在HQL中)将它们缩短到可怜的MS SQL可以“比较”的东西
答案 1 :(得分:0)
非常感谢波西米亚人指出我正确的方向。他的出色答案值得更多投票。
是的,这是MS SQL Server的限制,特别是它无法处理带有 distinct 的“text”字段,但更多的是我不明白 distinct 将比较它返回的实体中的所有字段,而不仅仅是ID字段。
因此我的答案是重新配置我的HQL,以便它只返回我感兴趣的字段,而不是整个用户实体。现在看来是这样的:
public List<Object[]> retrieveAllRequesters() { return hbSession().createQuery("select distinct r.requester.id, r.requester.name from Request r").list(); }