1

私はこのようなことをしようとしていますが、@ElementCollectionの代わりに@One-To-Manyを使用しています。

public class Book {
    ...
    @ElementCollection
    Set<String> tags;
    ...
}

これにより、2つのテーブルが作成されます。1つはBook用で、もう1つは(BookID、Tag)付きのタグ用で、@ ElementCollectionでCriteriaを使用できないという事実を除いて、正常に機能します。

そこで、それを変更して、タグのラッパークラスを作成しました。

public class Book {
    ...
    @OneToMany(...)
    Set<BookTag> tags;
    ...
}


public class BookTag {
    ...
    String tag;
    ...
}

問題は、@ OneToManyアノテーションhibernateを使用すると、3つのテーブルが作成されることです。1つは本用、1つはタグ用、もう1つは本とタグを結合するためのものです。このソリューションは完全に機能しますが、Tagクラスには文字列のみが含まれているため、3つではなく2つのテーブルが必要です。

@OneToManyを使用して、@ ElementCollectionの場合と同じようにHibernateに2つのテーブルを作成させる方法はありますか?

4

2 に答える 2

2

はい、OneToManyがデフォルト(結合テーブルを使用)の代わりに結合列を使用する必要があることを指定することにより、次のようになります。

@OneToMany(...)
@JoinColumn(name = "BOOK_ID")
private Set<BookTag> tags;
于 2012-06-27T21:19:43.350 に答える
0

このクエリは、@ElementCollectionJPA基準を使用して実行できます。メタモデルを使用しているとすると、次のようになります。

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Book> cq = cb.createQuery(Book.class);
Root<Book> book = cq.from(Book.class);

cq.select(book).where(cb.equal(book.join(Book_.tags), "fanfic"));

TypedQuery<Book> query = em.createQuery(cq);

メタモデルを使用していない場合、それは実質的に同じですが、おそらくを使用する必要がありますjoinSet

そのクエリは、かなりの意味があります。唯一の驚くべき点は、ではなくを実行する必要があるjoinことです。これは、単一のプロパティではなく複数のプロパティでgetあるためですが、その個々の要素を調べています。tags

あなたはまた、より自然に読むことを期待するかもしれません

cq.select(book).where(cb.isMember("fanfic", book.get(Book_.tags)));

動作します。おそらく、いくつかのJPA実装ではそうなります。しかし、Hibernate(4.1.4)では、そうではありません。構文エラーで爆発します。これはHibernateのバグHHH-5209のようです。

于 2012-07-06T22:30:38.257 に答える