2017-07-26 11 views
2

私はプライベートメッセージングデータベーススキーマを探していましたが、現在はメッセージを格納および取得するための基本的なdbスキーマを構築しようとしています。 これは、メッセージの実体である:HQLでSELECT DISTINCTを使用する

@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 
} 

とスレッドの実体は単なるIDです:私はHQLを使用しています

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(); 
} 

:これは私のクエリを呼び出す方法がある

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

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

    // getters and setters 
} 

dbを照会する。 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があります。

私が試した他のすべてのクエリは、(distinctの代わりに)すべてのメッセージを返すか、上記のエラーを投げた。私はCriteriaAPIをHQLよりも遅く、私が持っている他のコードはHQLで書かれていると読んでいないので、私は1つのメソッドに固執するつもりです。 私は何が欠けていますか?

+0

試してみてください。SELECT m、m.thread_Id FROMメッセージm WHERE(m.sender.id =:id OR m.receiver.id =:id)GROUP BY m.thread_id ORDER BY m.sent_date DESC) ' – fg78nc

+0

私はこのエラー: 'java.lang.IllegalArgumentException:要求された結果の種類[メッセージ]'を使用して複数の戻り値を持つクエリに対してTypedQueryを作成できません。 – Aria

+0

DISTINCTでどのようなエラーが発生しますか?生成されたSQLを投稿してください。 – fg78nc

答えて

0

DISTINCTこの場合の作品はうまくいくはずです。サブクエリで別のthreadエンティティを取得するときに問題が発生すると、外部クエリはサブクエリの結果セットに基づいてmessageを取得しますが、ユニークな「メッセージ」エンティティを取得していないのはそれぞれのmessageエンティティ一意のいくつかのユニークなものと結びついてください。thread経由で

私はここでは、最初に取得(最初のみ)

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) 

のクエリを変更することを提案(messageのPK(またはIDで))最古のメッセージを取得することにより、それぞれの固有のthreadに関連したmessageエンティティmin()

関連する問題