【问题标题】:How to create an 'instance of' -like query in JPA 2.0?如何在 JPA 2.0 中创建类似“实例”的查询?
【发布时间】:2011-10-24 04:15:20
【问题描述】:

假设我们有一个抽象的@Entity Animal,以及几个扩展 Animal 的实体类,包括 Dog、Cat、Monkey 和 Bat。

如何根据扩展实体的类过滤结果?

示例: 用户可以在复选框中选择要检索的实体。

[ ] Dog
[X] Cat
[X] Monkey
[ ] Bat

现在我想用Animal 类中定义的(命名)查询检索实体。我可以在查询中输入什么样的查询参数,以便只返回 Cat 和 Monkey 对象?

【问题讨论】:

    标签: java jpa jpa-2.0 jpql


    【解决方案1】:

    我不确定 JPA 是否支持它,但不管继承策略如何,在 Hibernate 中实现它的方式,因此即使您没有鉴别器(或没有将其映射为属性) ) 是使用隐含的class 属性:

    String jpql = "select a from Animal a where a.class in (:classes)";
    Query q = em.createQuery(jpql).setParameter("classes", 
                                                Arrays.asList(Cat.class, Monkey.class));
    

    编辑:

    我刚刚发现在 JPA2 中可以使用 TYPE 运算符:

    String jpql = "SELECT a FROM Animal a WHERE TYPE(a) IN :classes";
    Query q = em.createQuery(jpql).setParameter("classes", 
                                                Arrays.asList(Cat.class, Monkey.class));
    

    【讨论】:

    • 当您删除 :classes 周围的括号时,它可以工作。谢谢。
    【解决方案2】:

    您可以使用鉴别器列和值仅搜索给定类型的某些子类型。默认情况下,鉴别器列的名称是 JPA 中的 DTYPE,类型是 String,值是类的名称。但是,您可以通过添加类级别注释@DiscriminatorColumn(name="KIND", discriminatorType=DiscriminatorType.INTEGER)(用于鉴别器列的名称和类型)和@DiscriminatorValue("1")(用于特定类的特定鉴别器值)来覆盖它。然后,您可以在 yoru JPQL 查询的 WHERE 子句中使用它来仅获取某些子类型,例如:WHERE DTYPE="Dog" OR DTYPE="Cat"

    【讨论】:

    • 感谢您的回答!我会尝试 ... AND a.dtype IN :dtypes ... 其中 dtypes 是一个 Collection 看看它是怎么回事。
    • 如果您对此有疑问(即使用 dtype=ClassName 的默认值)尝试在您的子类上添加注释以配置每个子类的特定鉴别器列名称和值,然后在您的查询。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-22
    • 2021-06-17
    • 1970-01-01
    • 2017-08-24
    相关资源
    最近更新 更多