java - 使用 JPA/Hibernate 在集合中搜索

标签 java hibernate jpa

我想从我定义的包含集合的对象中进行查询。对象看起来像这样:

@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”可以有很多规则,如您所见......那么我该怎么做呢?

最佳答案

您在寻找成员吗? 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 。问题不在于查询本身,而在于参数绑定(bind)。使用时:

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

Hibernate 绑定(bind)枚举的序列化版本(在我的例子中,查询只返回任何内容)。但是,使用以下内容对我有用:

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

更新#2:很抱歉,但我认为我无法提供进一步的帮助。当按照 Hibernate 3.4 和 HSQLDB 的建议使用时,我发布的关于枚举集合上的 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 部分有关。

引用文献

  • JPA 1.0 规范
    • 第 4.6.12 节“集合成员表达式”
  • Hibernate 核心引用指南

关于java - 使用 JPA/Hibernate 在集合中搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3940983/

相关文章:

java - 与创建 JSON 相比,是否有一种在 Java 中创建 xml 的简单方法

java - 在 Java 中下载并解析 XML 文件

java - hibernate 教程。 Maven 编译时出现 MojoFailureException

java - 定时器正在创建多个定时器实例

java - 使用枚举进行 HQL 查询

hibernate - 通过单列而不是复合主键连接

java - 带有 Java 8 Streams 分离对象的 Spring Data JPA 存储库?

java - Hibernate - 在 Linux 和 Windows 上的不同行为

mysql - 从服务器接收到的字段的未知字符集索引

java - 一对一关系,只保留外键