简体   繁体   English

JPQL (JPA) 查询 SELECT DISTINCT ORDERED BY 遇到了一些问题

[英]Got some troubles with JPQL (JPA) query SELECT DISTINCT ORDERED BY

as in title i got some problems with query in JPQL如标题所示,我在 JPQL 中遇到了一些查询问题

that's the query I'm using:这就是我正在使用的查询:

@Query(value = "SELECT DISTINCT o.idWhom FROM Message o WHERE o.idWho = ?1 ORDER BY o.date DESC")
    List<Users> allCorrespondents(Users user);

Class message :班级留言

public class Message {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @NotBlank
    private String content;

    @Temporal(TemporalType.TIMESTAMP)
    private Date date = new Date();

    boolean read = false;

    @ManyToOne
    @JoinColumn(name = "id_who")
    private Users idWho;

    @ManyToOne
    @JoinColumn(name = "id_whom")
    private Users idWhom;
}

Error I've got:我遇到的错误:

2022-06-17 13:02:22.435 ERROR 2304 --- [nio-8080-exec-2] c.e.h.S.CustomAuthorizationFilter        : 
Error logging in: Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet

Although I am not able to prove it through issue tickets, I have done enough investigation to believe that this issue occurs to hibernate version previous from 5. (Example Hibernate 4 !) with database being used Oracle .虽然我无法通过问题单证明这一点,但我已经做了足够的调查,相信这个问题发生在从 5 开始的休眠版本上。(例如休眠 4 !)使用数据库Oracle

What the issue seems to be is the following:问题似乎如下:

When you have written the JPQL query SELECT DISTINCT o.idWhom FROM Message o you would expect that the entities would be filtered to be distinct after the execution of the SQL query, where the mapper would filter out the distinct entities.当您编写 JPQL 查询SELECT DISTINCT o.idWhom FROM Message o时,您会期望在执行 SQL 查询后实体将被过滤为不同的,其中映射器将过滤掉不同的实体。

For some reason however in those versions I mention above what actually happens is that the distinct is passed in the SQL query and what actually executes is the following:但是由于某种原因,在我上面提到的那些版本中,实际发生的是在 SQL 查询中传递了 distinct ,实际执行的内容如下:

SELECT DISTINCT idh.id_column FROM O_TABLE o JOIN IDWHOM_TABLE idh on (o.id_foreign_key_column = idh.id_column

As you can see this select query does not return in result set all columns that are needed from mapper to build the entity but only returns the id column.如您所见,此选择查询不会在结果集中返回映射器构建实体所需的所有列,而仅返回 id 列。 Therefore the mapper is not able to extract from ResultSet all columns needed to build the entity and you get the error that you get could not extract ResultSet .因此,映射器无法从 ResultSet 中提取构建实体所需的所有列,并且您会收到could not extract ResultSet的错误。

A workaround I have found, is that it is able to work when distinct is placed on some primitive field and not on an entity, so you can use this to your advantage to bypass this issue with the following approach:我发现的一种解决方法是,当 distinct 放置在某个原始字段而不是实体上时,它能够工作,因此您可以利用它来利用以下方法绕过此问题:

This supposes that the entity Users has as id a field named id .这假设实体Users有一个名为id

    @Query(value = "SELECT us FROM Users us where us.id in (SELECT DISTINCT o.idWhom.id FROM Message o WHERE o.idWho = ?1)") 
    List<Users> allCorrespondents(Users user);

I have excluded the ordering which you have in your original query since even from logical point of view seems wrong.我已经排除了您在原始查询中的排序,因为即使从逻辑角度来看似乎也是错误的。 A User entity can have multiple messages.一个用户实体可以有多个消息。 How could you order the returned users just from created date of messages?您如何仅从消息的创建日期订购返回的用户? This field is not able to order Users themselves.该字段不能对用户自己进行排序。 It could be used to order messages only.它只能用于订购消息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM