使用条件API获取具有特定元素的所有对象在字符串集合中

时间:2010-05-27 11:32:41

标签: java hibernate

我正在尝试构建一个Hibernate Criteria查询来查找集合中具有特定元素的实体。

我们可以举一个看起来像这样的Book -object:

public class Book {
  private Long id;
  private String title;
  private Set<String> authors = new HashSet<String>();
}

实体映射如下:

<class name="Book" table="Book">
    <id name="id" column="BOOK_ID">
        <generator class="native"/>
    </id>
    <property name="title"/>
    <set name="authors" table="Book_Authors">
        <key column="BOOK_ID"/>
        <element type="string" column="AUTHORS"/>
    </set>
</class>

现在我想找出Matt写的是哪些书。使用纯SQL,我可以执行以下查询:

String author = "Matt";
String query =  "SELECT * FROM Book " + 
                "WHERE BOOK_ID IN " +
                "(SELECT BOOK_ID FROM Book_Authors " + 
                "WHERE authors = :author )";
List<Book> result = session.createSQLQuery(query)
        .addEntity(Book.class)
        .setParameter("author", author)
        .list();

这一切都很好,而且我得到了Matt参与写作的所有书籍。但是,我工作的项目使用Criteria API而不是原始SQL,我还没有找到一种方法来表达该表单中的相同查询。我已经看了Restrictions API,我发现最接近的是Restions.in(propertyName,collection),但是反过来(对象中有一个值,要匹配的值很多)。

有什么想法吗?

3 个答案:

答案 0 :(得分:4)

您是否尝试过使用HQL

SELECT bk FROM Book bk WHERE :author IN bk.authors

HQL通常比Criteria更强大,所以你可能会坚持使用它。

答案 1 :(得分:2)

最简单的方法是使用sql限制,现在:

criteria.add(Restrictions.sqlRestriction("BOOK_ID IN " +
                "(SELECT BOOK_ID FROM Book_Authors " + 
                "WHERE authors = " + author + " )"));

或者您可以编写自己的标准。

答案 2 :(得分:2)

您目前无法使用Criteria API查询值类型集合。 Here是问题,它链接到描述相同问题的论坛帖子。

但是,

HQL可以正常工作。