Java 休眠@One-To-Many类似于@ElementCollection

Java 休眠@One-To-Many类似于@ElementCollection,java,hibernate,hibernate-mapping,Java,Hibernate,Hibernate Mapping,我正在尝试这样做,但是使用@One-to-Many而不是@ElementCollection public class Book { ... @ElementCollection Set<String> tags; ... } 公共课堂教材{ ... @元素集合 设置标签; ... } 这将创建两个表,一个用于Book,另一个用于带有(BookID,Tag)的标记,这可以正常工作,但我不能将条件用于@ElementCollection public

我正在尝试这样做,但是使用@One-to-Many而不是@ElementCollection

public class Book {
    ...
    @ElementCollection
    Set<String> tags;
    ...
}
公共课堂教材{
...
@元素集合
设置标签;
...
}
这将创建两个表,一个用于Book,另一个用于带有(BookID,Tag)的标记,这可以正常工作,但我不能将条件用于@ElementCollection

public class Book {
    ...
    @ElementCollection
    Set<String> tags;
    ...
}
因此,我对其进行了更改,并为标记创建了一个包装器类:

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


public class BookTag {
    ...
    String tag;
    ...
}
公共课堂教材{
...
@一个女人(…)
设置标签;
...
}
公共类图书标签{
...
字符串标签;
...
}
问题是使用@OneToMany annotation hibernate创建了3个表:一个用于书籍,一个用于标记,还有一个用于连接书籍和标记。这个解决方案非常有效,但我希望有2个表,而不是3个表,因为Tag类只包含一个字符串


有没有办法使用@OneToMany并使hibernate像使用@ElementCollection一样创建2个表?

是,指定OneToMany必须使用联接列而不是默认列(使用联接表):

@OneToMany(…)
@JoinColumn(name=“BOOK\u ID”)
私有集标签;

您可以使用JPA标准在
@ElementCollection
上执行该查询。假设您使用的是元模型,它如下所示:

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);

会有用的。也许在一些JPA实现中确实如此。但在Hibernate(4.1.4)中,情况并非如此;结果是出现了语法错误。这似乎是。

您确定不能在条件查询中使用元素集合吗?我们至少有相反的说法。在我使用ElementCollection的例子中,我得到了一个org.hibernate.MappingException:collection不是一个关联。然后我读了,觉得我不能使用ElementCollection和Criteria.interest。可能有一些查询可以使用元素集合进行,而有些查询不能。你想做什么查询?我需要列出所有包含某个标记的BOK。
cq.select(book).where(cb.isMember("fanfic", book.get(Book_.tags)));