Java 使用JPA/Hibernate在集合中搜索
我想从我定义的包含集合的对象中进行查询。对象如下所示:Java 使用JPA/Hibernate在集合中搜索,java,hibernate,jpa,Java,Hibernate,Jpa,我想从我定义的包含集合的对象中进行查询。对象如下所示: @Entity public class ValidationLog { @Embeddable public static class ValidationLogPK implements Serializable { private String dataKey; @Enumerated(EnumType.STRING) private DataType dataType;
@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)"
然而,这不起作用。不过,我不确定索引的功能。问题是,我希望获得指定类型、结果和规则的所有数据键。问题是,正如您所看到的,每个数据键都可能有许多规则。。。那我该怎么做呢 您正在寻找会员吗?在JPQL中类似这样的内容:
SELECT v.id.dataKey
FROM ValidationLog v
WHERE v.validationResult = :result
AND v.id.dataType = :type
AND :rule MEMBER OF v.validationRules
如果您不确定是否会这样做,我针对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元素时还有另一个问题,即。问题不在于查询本身,而在于参数绑定。使用时:
query.setParameter("rule", ValidationRule.FOO);
Hibernate绑定了一个序列化版本的枚举。在我的例子中,查询什么也不返回。但是,使用以下方法对我很有效:
query.setParameter("rule", ValidationRule.FOO.name());
更新2:我很抱歉,但我认为我无法进一步提供帮助。当我按照Hibernate 3.4和HSQLDB的建议使用时,我在enum集合上发布的关于in元素的内容对我很有用。以下是测试:
@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]
也许可以尝试简化查询以缩小问题范围。我不确定它是否与内部元素部分有关
工具书类
JPA1.0规范
第4.6.12节集合成员表达式
Hibernate核心参考指南
看起来我在JPQL方面遇到了与您相同的问题,成员:由:org.hibernate.hql.ast.QuerySyntaxException:子树的意外结束[从ValidationLog v中选择v.id.dataKey,其中v.validationResult=:result和v.id.dataType=:v.validationRules的类型和:规则成员]不幸的是,HQL变体也出现了类似的问题:原因是:org.hibernate.exception.sqlgrammareexception:无法执行query@Peter奇怪的是,我对HQL变体进行了测试,即在元素中使用,它只适用于Hibernate 3.5。我将用Hibernate EM 3.4测试它。我再次测试,现在得到了一个更好的错误:-由:org.postgresql.util.PSQLException引起:错误:运算符不存在:bytea=字符变化提示:没有运算符匹配给定的名称和参数类型。您可能需要添加显式类型转换。-我正在运行PostgreSQL,不知道这是否是数据库特有的问题?再次感谢Pascal。我遇到的最后一个问题是由我造成的错误,因此不再存在Hibernate问题。