2

私のモデルには、PersonとPuppyの2つのエンティティがあります(単純化するために:))。それらの間には1対多の関係があるので、各人は子犬のコレクションを持っています。

ここで、「John」という名前のすべての人をリストするだけでなく、子犬を2か月以上の人に制限するHQLクエリを作成します。

私の最初の試みは次のようになりました:

SELECT p FROM Person p
JOIN FETCH p.puppies pu
WHERE p.name = 'John'
AND pu.age > 2

ただし、このクエリでは、2か月以上前の子犬が少なくとも1匹いる人だけが選択され、若い子犬しかいない人は選択されないため、機能しません。そして、空の子犬リストだけでそれらを見たいです。

事実上、私は(擬似コード)のようなものを達成したいと思います:

SELECT p FROM Person p
JOIN FETCH p.puppies pu HAVING (pu.age > 2 )
WHERE p.name = 'John'
4

2 に答える 2

0

HQLは、さまざまな種類の結合をサポートしています。したがって、次のように左(外部)結合を使用できます。

FROM Person p
LEFT OUTER JOIN p.puppies pu
WHERE p.name = 'John'
AND pu.age > 2

これはあなたにも子犬のいないすべてのジョンを与えるはずです。あなたは「...しかし、若い人しかいない」と言います。それを完全に理解していない。明示的に宣言した場合、なぜ若い子犬の子犬を見たいのAND pu.age > 2ですか?

于 2013-01-12T20:08:14.083 に答える
0

Hibernateフィルターを使用して問題を解決でき ます

まず、フィルターを定義する必要がありました。

@Entity
@FilterDef(name="olderThan", parameters=@ParamDef( name="months", type="integer" ) )
public class Person{
  @OneToMany
  @Filter(name="olderThan", condition="age > :months")
  private List<Puppy> puppies;
}

そして、クエリフィルタを実行する前に、次のことを有効にする必要があります。

public class PersonRepository{
  @PersistenceContext
  private EntityManager em;

  public List<Person> findPeopleWithPoppiesLimitedToOlderThan(int months){
    em.unwrap(Session.class).enableFilter("olderThan").setParameter("months", months);
    return em.createQuery("SELECT p FROM Person LEFT JOIN FETCH p.puppies WHERE p.name = 'John'", Person.class).getResultList();
  }
}

そしてすべてが機能します。

于 2013-01-14T21:19:58.097 に答える