【问题标题】:Using SELECT DISTINCT in HQL在 HQL 中使用 SELECT DISTINCT
【发布时间】:2018-01-01 23:13:48
【问题描述】:

我一直在研究私人消息传递数据库模式,目前我正在尝试构建一个基本的数据库模式来存储和检索消息 - 没什么太复杂的。 这是消息实体:

@Entity
@Table(name="messages")
class Message {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id", unique=true, nullable = false)
    private int id;

    @ManyToOne(cascade = CascadeType.MERGE)
    @JoinColumn(name = "thread_id")
    private Thread thread_id;

    @Column(name="sent_date")
    private Date sent_date;

    @Column(name="message_body")
    private String message_body;

    @JoinColumn(name = "sender_id")
    private User sender;

    @JoinColumn(name = "receiver_id")
    private User receiver;


    // getters and setters
}

而 Thread 实体只是一个 id :

@Entity
@Table(name="threads")
class Thread {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id", unique=true, nullable = false)
    private int id;

    // getters and setters
}

这是调用我的查询的方法:

public List<Message> getDistinctMessagesForUser(int id) {
    return em.createQuery("SELECT m FROM Message m WHERE m.thread_id IN (SELECT DISTINCT m.thread_id FROM Message m WHERE (m.sender.id =:id OR m.receiver.id =:id)) ORDER BY m.sent_date DESC", Message.class)
            .setParameter("id", id)
            .getResultList();
}

我正在使用 HQL 来查询数据库。我正在尝试使用 SELECT DISTINCT 获取每个线程的最新消息,但我似乎无法使其工作。

我试过用这个:

SELECT m FROM Message m WHERE (m.sender.id =:id OR m.receiver.id =:id) GROUP BY m.thread_id ORDER BY m.sent_date DESC)

但我一直收到此错误:

ERROR: column "message0_.id" must appear in the GROUP BY clause or be used in an aggregate function

我也尝试了link 中显示的方法,但错误是由于查询有 e 和 m 造成的。

我尝试的所有其他查询要么返回所有消息(而不是不同的),要么抛出我上面描述的错误。我不想使用 CriteriaAPI,因为我读到它比 HQL 慢,而且我拥有的其他代码是用 HQL 编写的,我打算坚持使用一种方法。 我错过了什么?

【问题讨论】:

  • 试试SELECT m, m.thread_Id FROM Message m WHERE (m.sender.id =:id OR m.receiver.id =:id) GROUP BY m.thread_id ORDER BY m.sent_date DESC)
  • 它给了我这个错误:java.lang.IllegalArgumentException: Cannot create TypedQuery for query with more than one return using requested result type [Message]
  • 您在 DISTINCT 上遇到什么样的错误?请发布生成的 SQL。
  • @fg78nc 我已经把我使用 DISTINCT 得到的错误放在了问题中
  • 我没有在您的问题中看到生成的 SQL,并使用 DISTINCT 进行查询

标签: hibernate select group-by hql distinct


【解决方案1】:

DISTINCT 在这种情况下有效,它应该有效。问题出在您的逻辑中,因为您在子查询中检索不同的thread 实体,然后您的外部查询根据子查询的结果集检索message,但是您没有以这种方式获得唯一的“消息”实体,因为每个message 实体可以与几个甚至唯一的threads 相关联。

我建议更改查询

List<MyMessage> myMes = em.createQuery(
                "SELECT m from MyMessage m where m.id "
                + "in (select min(m2.id) from MyMessage m2 group by m2.thread_id) "
                + "and (m.sender.id =:id OR m.receiver.id =:id)", MyMessage.class)
               .setParameter("id", 1L)

在这里,我们通过min() 获取最早的消息(通过message 的PK(或ID)),检索与每个唯一thread 关联的第一个(也是唯一一个)message 实体。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-30
    • 2012-10-21
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多