2016-09-29 6 views
2

これは基本的なように見えるかもしれませんが、遅れており、次の点で問題があります。HQLは条件付きで参加しました

class Group { 

    @Id 
    String id; 
} 

class Participation { 

    @Id 
    String id; 

    @ManyToOne 
    @JoinColumn(name = "GROUP_ID") 
    Group group; 

    @ManyToOne 
    @JoinColumn(name = "USER_ID") 
    User user; 
} 

class User { 

    @Id 
    String id; 

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY) 
    Set<Participation> participations; 
} 

Class diagram

ので

参加 - > 1グループ

とユーザー1 < - 私は、とのすべてのグループを取得するにはどうすればよい> N参加

指定されたユーザ、関連する参加(またはnullはありません)?私は...フェッチに参加したが、これまで無駄に

多くのおかげで、

CN

PSをプレーしてきました。私は、このようにSQLでこれを行うことができます。

select g.d, p.id 
from group as g 
left join participation as p 
on p.group_id = g.id and p.user_id = 2; 
+0

編集:ダイアグラムを追加し、より良いsqlソリューション... – ChambreNoire

答えて

-1

あなたはGroupエンティティでparticipation関係をマッピングする必要があります。 ParticipationGroupとの関係は1..Nある場合:

class Group { 
    String id 
    List<Participation> participations 
} 

JPQLとすることができる:List<Object[]>Object[0]がグループIDであり、Object[1]が参加IDである)として

SELECT g.id, p.id FROM Group g 
JOIN g.participations p 
JOIN p.user user 
WHERE user.id = :idUser 

あなたはこの情報を受信することができます。 SELECT NEWを使用してください。

SELECT g.id, p.id FROM Group g, Participation p 
JOIN p.user user 
JOIN p.group groupp 
WHERE g.id = groupp.id 
AND user.id = :idUser 

をしかし、あなたは、この戦略を使用してLEFT JOINを行うことはできません。

マップグループ/参加の関係がなければ、あなたが行うことができます。上記のクエリはJOINのようになります。

Hibernateでは、クエリを作成する関係の側面をマッピングするのが普通です。ですから、最初のアプローチをお勧めします。

+0

私は参加とグループの関係が1:1ではないことを心配しています(元の質問に図を追加しました)。 – ChambreNoire

+0

@ ChambreNoire、問題ありません!私は自分の質問を編集しましたが、同じ方法で動作します – Dherik

+0

グループ>参加協会を追加しないと、それはできません。 – ChambreNoire

3

(おそらくいくつかのHQL自体にタイプミスが、考えは正しいはずです)、あなたのSQLと説明に基づいて、求めている何

Userに基づいて、すべてのParticipation(およびそのがGroup対応を)見つけるされ、より良いそれを作るために単に

select p.id, p.group.id from Participation p where p.user.id = :userId 

これは、あなたの代わりにエンティティをフェッチする必要があります

from Participation p left join fetch p.group where p.user.id = :userId 

あなたがしようとしていたことを理解する上で、いくつかの混乱がありました。 条件に関係なくすべてのグループが必要です。また、特定のユーザーに対して、そのユーザーが関与しているすべてのグループおよび参加者を検索する必要があります。

それは右外部結合使用可能である必要がありますが:

select g, p from Participation p 
    right outer join p.group g 
    where p.user.id=:userId 

または、休止状態(> = 5.1?)の後のバージョンでは、それが明示的な結合が可能(あなたがかもしれない、前に試していません

select g, p from Group g 
    left outer join Participation p 
     with p.group = g 
    left outer join p.user u 
    where u.id = :userId 

それとも、しかし、私はむしろ、あなたのケースで単純なクエリにそれらを分けるだろうなサブクエリなどのような他の技術を使用して行うことができます:あなたはJPQLを使用している場合、()onwithを交換して)それを試してみますコード内の単純な集約

基本的な考え方は、すべてのグループの

  1. 照会することです。そして、あなたがフォームにあなたに簡単にそれらを集約することができfrom Participation p join fetch p.group where p.user.id=:userId

:ユーザーのすべての参加のためのfrom Groups

  • クエリをほしい、例えばMap<Group, List<Participation>>、またはさらに意味のある値オブジェクトである。

    利点は、データアクセスクエリがより簡単で再利用可能であることです(DAO /リポジトリファインダメソッドでラップしている場合)。 DBへのもう1回の往復で、ここで明白なパフォーマンスの影響はありません。

  • +1

    ありがとうございます。ただし、この方法以外では、指定したユーザーの参加なしでグループを取得しません。 – ChambreNoire

    +0

    私はdbmsを手に入れていませんが、ユーザIDを使ってあなたの例として左結合を行っても、参加者だけがあなたにグループを与えるべきですか?そして、あなたは、 "与えられたユーザーのために、与えられた参加"を求めました。これは、あなたが誰も参加しないことは、あなたが求めたものと矛盾しています。とにかく、 '参加者からの参加を試してみてください。p.user u.id =:useridまたはuがヌルです.' –

    +0

    あなたはあなたが尋ねたことを誤解していたと思います。あなたは実際にすべてのグループを正しく望んでいますか?とにかくiirc、HQLはRight Joinをサポートしていますので、参加権を持つことから始めてp.groupに参加できますか? –

    関連する問題