Я имею к следующему объекту объекта
@Entity
public class Foobar {
...
private List<String> uuids;
...
}
Теперь я хотел бы сделать запрос критериев, который выберет весь Foobar pojos, список uuids которого содержит строку "abc123", я просто не уверен, как сделать соответствующий критерий.
Я предполагаю, что вы используете версию Hibernate, которая реализует JPA 2.0. Вот решение JPA 2.0, которое должно работать с любой совместимой реализацией.
Добавьте в uuids
аннотацию JPA @ElementCollection
. Не используйте Hibernate @CollectionOfElements
, как упоминалось в некоторых других комментариях к ответу. Последний имеет эквивалентную функциональность, но считается устаревшим .
Foobar.java
будет выглядеть примерно так:
@Entity
public class Foobar implements Serializable {
// You might have some other id
@Id
private Long id;
@ElementCollection
private List<String> uuids;
// Getters/Setters, serialVersionUID, ...
}
Вот как вы можете создать CriteriaQuery
, чтобы выбрать все Foobar
s, чьи uuids
содержат «abc123».
public void getFoobars() {
{
EntityManager em = ... // EM by injection, EntityManagerFactory, whatever
CriteriaBuilder b = em.getCriteriaBuilder();
CriteriaQuery<Foobar> cq = b.createQuery(Foobar.class);
Root<Foobar> foobar = cq.from(Foobar.class);
TypedQuery<Foobar> q = em.createQuery(
cq.select(foobar)
.where(b.isMember("abc123", foobar.<List<String>>get("uuids"))));
for (Foobar f : q.getResultList()) {
// Do stuff with f, which will have "abc123" in uuids
}
}
Я создал автономную программу для проверки концепции, играя с ней. Я не могу сейчас это вытолкнуть. Прокомментируйте, если вы хотите, чтобы POC был помещен в github.
Для начала, я не думаю, что Hibernate может отображать List
. Однако он может отображать список других сущностей.
Итак, если ваш код выглядит примерно так:
@Entity
public class Foobar {
private List<EntityObject> uuids;
...
}
А EntityObject
имеет String
-свойство с именем str
, критерии могут выглядеть следующим образом :
List<Foobar> returns = (List<Foobar>) session
.createCriteria.(Foobar.class, "foobars")
.createAlias("foobars.uuids", "uuids")
.add(Restrictions.like("uuids.str", "%abc123%"))
.list();
То, что вы спрашиваете, не поддерживается спящим режимом из коробки. См. http://opensource.atlassian.com/projects/hibernate/browse/HHH-869
В билете jira доступен обходной путь:
entityCriteria.add(Restrictions.sqlRestriction(
"fooAlias.id in (select e.id from foobar_table e, values_table v" +
" where e.id = v.entity_id and v.field = ?)", "abc123"), Hibernate.String)) ;
Вы можете использовать запрос, как в примере ниже, или преобразовать его в NamedQuery. К сожалению, похоже, что это невозможно сделать с помощью критериев.
List<Foobar> result = session
.createQuery("from Foobar f join f.uuids u where u =: mytest")
.setString("mytest", "acb123")
.list();