Поиск в коллекции с помощью JPA / Hibernate - PullRequest
2 голосов
/ 15 октября 2010

Я хотел бы сделать запрос из определенного мной объекта, который содержит коллекцию. Объект выглядит так:

@Entity
public class ValidationLog {
    @Embeddable
    public static class ValidationLogPK implements Serializable {
        private String dataKey;
        @Enumerated(EnumType.STRING)
        private DataType dataType;
    }

    @EmbeddedId
    private ValidationLogPK id;

    @Enumerated(EnumType.STRING)
    private ValidationResult validationResult;

    @CollectionOfElements(fetch = FetchType.EAGER)
    @JoinTable
    @Enumerated(EnumType.STRING)
    private Set<ValidationRule> validationRules;
}

И запрос выглядит примерно так:

"select v.id.dataKey from ValidationLog v " + 
    " where v.validationResult = :result" +
    " and v.id.dataType = :type" +
    " and :rule in indices(v.validationRules)"

Однако это не работает. Функция «индексы» я не уверен, хотя. Дело в том, что я хотел бы получить все «dataKeys» определенного типа, результата и правила. Проблема в том, что у каждого «dataKey» может быть много правил, как вы видите ... Так как мне это сделать?

1 Ответ

4 голосов
/ 15 октября 2010

Вы ищете MEMBER OF?Примерно так в JPQL:

SELECT v.id.dataKey
FROM ValidationLog v
WHERE v.validationResult = :result
  AND v.id.dataType = :type
  AND :rule MEMBER OF v.validationRules

Если вы сталкиваетесь с HHH-5209 (не уверен, что вы сообщите об этой проблеме в Hibernate 3.5), попробуйте вариант HQL:

SELECT v.id.dataKey
FROM ValidationLog v
WHERE v.validationResult = :result
  AND v.id.dataType = :type
  AND :rule IN elements(v.validationRules)

Обновление: Есть еще одна проблема при использовании in elements для коллекции перечислений , а именно HHH-5159 .Проблема не в самом запросе, а в привязке параметра.При использовании:

query.setParameter("rule", ValidationRule.FOO);

Hibernate связывает сериализованную версию enum (в моем случае запрос просто ничего не возвращает).Однако использование следующего помогло мне:

query.setParameter("rule", ValidationRule.FOO.name());

Обновление № 2: Извините, но я не думаю, что смогу помочь в дальнейшем.То, что я написал о in element на коллекции enum, работает для меня, когда используется, как предложено в Hibernate 3.4 и HSQLDB.Вот тест:

@Test
// http://opensource.atlassian.com/projects/hibernate/browse/HHH-5159
public void testQueryWithInElementOfCollectionOfElementsOfEnums() {
    Person person = new Person("Bruce", "Wayne");
    Set<SomeEnum> someEnums = new HashSet<SomeEnum>();
    someEnums.add(SomeEnum.ONE);
    someEnums.add(SomeEnum.TWO);
    someEnums.add(SomeEnum.FIVE);

    person.setSomeEnums(someEnums);

    session.persist(person);

    String queryString = "SELECT p FROM Person p WHERE :someEnum in elements(p.someEnums)";

    Query query = session.createQuery(queryString);
    // query.setParameter("someEnum", SomeEnum.FIVE); // doesn't work, see HHH-5159
    query.setParameter("someEnum", SomeEnum.FIVE.name());
    List actual = query.list();
    assertNotNull(actual);
    assertEquals(1, actual.size());
}

И журналы:

...
12:40:06.353 [main] DEBUG org.hibernate.SQL - 
    select
        person0_.id as id11_,
        person0_.dept as dept11_,
        person0_.firstName as firstName11_,
        person0_.gender as gender11_,
        person0_.lastName as lastName11_ 
    from
        Person person0_ 
    where
        ? in (
            select
                someenums1_.element 
            from
                Person_someEnums someenums1_ 
            where
                person0_.id=someenums1_.Person_id
        )
<b>12:40:06.357 [main] TRACE org.hibernate.type.StringType - binding 'FIVE' to parameter: 1</b>
12:40:06.359 [main] DEBUG org.hibernate.jdbc.AbstractBatcher - about to open ResultSet (open ResultSets: 0, globally: 0)
<b>12:40:06.361 [main] TRACE org.hibernate.type.IntegerType - returning '1' as column: id11_</b>
12:40:06.363 [main] DEBUG org.hibernate.loader.Loader - result row: EntityKey[com.acme.domain.Person#1]

Возможно, попытайтесь упростить запрос, чтобы сузить проблему.Я не уверен, что это связано с in element деталью.

Ссылки

  • JPA 1.0 Спецификация
    • Раздел 4.6.12 «Выражения членов коллекции»
  • Справочное руководство по Hibernate Core
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...