1

我正在尝试做这样的事情,但使用@One-To-Many 而不是@ElementCollection。

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

这将创建两个表,一个用于 Book,另一个用于带有 (BookID, Tag) 的标签,除了我不能将 Criteria 与 @ElementCollection 一起使用这一事实之外,它工作正常。

所以我改变了它并为标签制作了一个包装类:

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


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

问题是使用 @OneToMany 注释休眠创建 3 个表:一个用于书籍,一个用于标签,一个用于连接书籍和标签。这个解决方案工作得很好,但我想要 2 个表而不是 3 个,因为 Tag 类只包含一个字符串。

有什么方法可以使用 @OneToMany 并像使用 @ElementCollection 一样让休眠创建 2 个表?

4

2 回答 2

2

是的,通过指定 OneToMany 必须使用连接列而不是默认值(使用连接表):

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

您可以@ElementCollection使用 JPA 条件执行该查询。假设您使用的是元模型,它看起来像这样:

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.

该查询具有合理的意义。唯一令人惊讶的是需要做 ajoin而不是 a get,这是因为tags它是复数属性,而不是单数属性,但您正在查看它的各个元素。

您可能还期望阅读更自然

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

会工作。也许对于一些 JPA 实现它确实如此。但是对于 Hibernate (4.1.4),它不会;它因语法错误而爆炸。这似乎是休眠错误 HHH-5209

于 2012-07-06T22:30:38.257 回答