Я пытаюсь создать Быть в спящем режиме запрос Критериев для нахождения объектов, которые имеют определенный элемент в наборе.
Мы можем взять в качестве примера Книгу - объект, который похож на это:
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 был частью записи. Проект я работаю в, однако, использует Критерии API вместо необработанного SQL, и я не нашел способ выразить тот же запрос в той форме. Я смотрел на Ограничениях API и самое близкое, которое я нашел, Restions.in (propertyName, набор), но это работает наоборот (одно значение в объекте, много значений для соответствия против).
Какие-либо идеи?
Самый простой способ - это использовать ограничение sql на данный момент:
criteria.add(Restrictions.sqlRestriction("BOOK_ID IN " +
"(SELECT BOOK_ID FROM Book_Authors " +
"WHERE authors = " + author + " )"));
Или вы можете написать свой собственный критерий.
Пробовали ли вы использовать HQL?
SELECT bk FROM Book bk WHERE :author IN bk.authors
HQL обычно более мощный, чем Criteria, поэтому вы можете застрять с ним.
В настоящее время невозможно запросить коллекцию типов значений с помощью API Criteria. Вот проблема, которая ссылается на сообщения форума, описывающие ту же проблему.
HQL работает, однако.