1

次の 2 つのテーブル (Cats with Kittens) があるとします。

==== Cat.java ====
@Id @GeneratedValue( strategy = GenerationType.IDENTITY ) 
private long id;

@Column( unique = true, nullable = false )
private String name;

@OneToMany @JoinColumn( name = "cat_id" )
private List<Kitten> kitten;

==== Kitten.java ====
@Id @GeneratedValue( strategy = GenerationType.IDENTITY ) 
private long id;

@Column( unique = true, nullable = false )
private String name;

次のデータで

Cat(id, name)
Cat(1, "Cat 1")
Cat(2, "Cat 2")

Kitten(id, cat_id, name)
Kitten(1, 1, "Kitten 1")
Kitten(2, 1, "Kitten 2")
Kitten(3, 2, "Kitten 3")
Kitten(3, 2, "Bad Kit")

ここで、名前に「kitten」が含まれる子猫を飼っているすべての猫を見たいと思います。

list = sess().createCriteria( Cat.class ).createAlias( "kitten", "kitten" )
.add( Restrictions.like( "kitten.name", "%kitten%" ) ).list();

前のコマンドは、結合により重複したエントリが取得され、たとえば count と maxresult が機能しないため、あまり適切ではありません。これは十分に文書化された問題であり、代わりにサブクエリを使用することが言及されています。

私はこのようなことを考えています(ただし、Criteria-Apiを使用):

from Cat where id in
(select cat_id from Kitten where name like '%kitten%')

休止状態では「cat_id」へのアクセスが許可されず、このクエリだけで双方向にしたくないため、これは機能しません。

4

2 に答える 2

2

cat ID を取得するためにプロジェクションを追加するだけの場合、クエリは、使用したいサブクエリです。したがって、次のものが必要です。

DetachedCriteria acceptedCatIds = DetachedCriteria.forClass(Cat.class);
acceptedCatIds.createAlias("kitten", "kitten")
              .add(Restrictions.like("kitten.name", "%kitten%" ))
              .setProjection(Projections.id());

Criteria acceptedCats = session.createCriteria(Cat.class)
acceptedCats.add(Subqueries.propertyIn("id", acceptedCatIds));
于 2013-09-15T18:33:25.517 に答える
0

Cat への参照を含む Kitten も用意することを強くお勧めします。子猫側と猫側の両方から一貫した関係を維持するには、もう少し注意が必要ですが、それだけの価値はあります。

class Cat {

    @Id @GeneratedValue( strategy = GenerationType.IDENTITY ) 
    private long id;

    @OneToMany(mappedBy="parent")
    private List<Kitten> kitten;
}

class Kitten {

    @Id @GeneratedValue( strategy = GenerationType.IDENTITY ) 
    private long id;

    @Column( unique = true, nullable = false )
    private String name;

    @ManyToOne
    @JoinColumn( name = "cat_id" )
    private Cat parent;
}

HQL は、必要に応じてシンプルになる必要があります。

from Cat c where c in
(select parent from Kitten where name like '%kitten%')

あるいは

select distinct parent from Kitten where name like '%kitten%'
于 2013-09-16T03:33:43.403 に答える