我想从我定义的包含集合的对象进行查询。对象看起来像这样:
@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”都可以有很多规则,你可以看到......那么我该怎么做呢?
答案 0 :(得分:4)
您在寻找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绑定了枚举的序列化版本(在我的例子中,查询只返回任何内容)。但是,使用以下方法对我有用:
query.setParameter("rule", ValidationRule.FOO.name());
更新#2:我很抱歉,但我认为我无法继续提供帮助。当我按照Hibernate 3.4和HSQLDB的建议使用时,我发布的关于enum集合的in element
的内容对我有用。这是测试:
@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 ) 12:40:06.357 [main] TRACE org.hibernate.type.StringType - binding 'FIVE' to parameter: 1 12:40:06.359 [main] DEBUG org.hibernate.jdbc.AbstractBatcher - about to open ResultSet (open ResultSets: 0, globally: 0) 12:40:06.361 [main] TRACE org.hibernate.type.IntegerType - returning '1' as column: id11_ 12:40:06.363 [main] DEBUG org.hibernate.loader.Loader - result row: EntityKey[com.acme.domain.Person#1]
也许尝试简化查询以缩小问题范围。我不确定它与in element
部分有关。