hibernate - JPA 条件 API 查询子类属性

标签 hibernate jpa inheritance criteria criteria-api

我想执行匹配特定子类属性的查询,所以我尝试使用 treat() .

在这个例子中,我想要:

名称以“a”开头的所有科目,
或所有主体,即人,姓氏以“a”开头

private List<Subject> q1()
{
    CriteriaBuilder b = em.getCriteriaBuilder();

    CriteriaQuery<Subject> q = b.createQuery(Subject.class);
    Root<Subject> r = q.from(Subject.class);
    q.select(r);
    q.distinct(true);
    q.where(
        b.or(
            b.like(r.get(Subject_.name), "a%"),
            b.like(b.treat(r, Person.class).get(Person_.lastName), "a%")));

    return em.createQuery(q).getResultList();
}

显然,Person扩展 Subject , Subject是抽象的,继承是SINGLE_TABLE , 和 Subject@DiscriminatorOptions(force = true)由于其他原因(非影响因素)。

但是生成的SQL是这样的:
select distinct subject0_.ID as ID2_71_, subject0_.CODE as CODE3_71_, ...
from SUBJECT subject0_ 
where subject0_.DTYPE='Person' and (subject0_.name like 'a%' or subject0_.lastName like 'a%')

虽然我期待:
select distinct subject0_.ID as ID2_71_, subject0_.CODE as CODE3_71_, ...
from SUBJECT subject0_ 
where subject0_.name like 'a%' or (subject0_.DTYPE='Person' and subject0_.lastName like 'a%')

有没有办法使用标准构建器生成预期的查询?

请注意
  • 使用另一个根 - q.from(Person.class)
  • 使用子查询 - q.subquery(Person.class)
  • 将姓氏字段向上移动到主题
  • 使用 native 查询
  • 使用实体图

  • Not Acceptable .

    我对可以直接在 WHERE 子句( 仅从 CriteriaBuilder 和/或单个 Root 产生,就像 treat() 子句)中声明和使用的东西感兴趣,如果它确实存在的话。

    最佳答案

    解决方案是,使用 Hibernate,在这个特定场景中,非常简单:

    private List<Subject> q1()
    {
        CriteriaBuilder b = em.getCriteriaBuilder();
    
        CriteriaQuery<Subject> q = b.createQuery(Subject.class);
        Root<Subject> r = q.from(Subject.class);
        q.select(r);
        q.distinct(true);
        q.where(
            b.or(
                b.like(r.get(Subject_.name), "a%"),
                b.and(
                    b.equal(r.type(), Person.class),
                    b.like(((Root<Person>) (Root<?>) r).get(Person_.lastName), "a%"))));
    
        return em.createQuery(q).getResultList();
    }
    

    请注意 双铸 ,避免编译错误,并允许在同一个表上执行查询子句。这会产生:
    select distinct subject0_.ID as ID2_71_, subject0_.CODE as CODE3_71_, ...
    from SUBJECT subject0_ 
    where subject0_.DTYPE in ('Office', 'Team', 'Role', 'Person', ...) 
        and (subject0_.name like 'a%' 
            or subject0_.DTYPE='Person' and (subject0_.lastName like 'a%'))
    

    无需更改模型或其他任何内容。

    关于hibernate - JPA 条件 API 查询子类属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34251930/

    相关文章:

    java - Hibernate 可嵌入继承

    java - 如何修复Hibernate的配置文件?

    java - 在 Spring Boot 应用程序上使用 Flyway 时如何在 H2 中加载初始数据?

    spring - @Query返回对象而不是实体

    javascript - 要求/导入已经在继承链的更高位置导入的类是错误的吗?

    python - 同时使用父属性和重写子属性的继承

    java - Spring GrantedAuthorities 和相关对象的 Hibernate 问题

    java - 遍历树 : Hibernate LazyFetch dto. getObjects() 与 Hibernate.initialize(dto.getObjects)

    java - 如何从JPA中具有相同值的一列中获取sql中的唯一行?

    c++ - 在派生类初始化器列表中初始化模板基类成员类型