【问题标题】:Invalid alias when joining two JPA entities via JPA 2.0 CriteriaBuilder通过 JPA 2.0 CriteriaBuilder 加入两个 JPA 实体时别名无效
【发布时间】:2016-08-29 19:11:19
【问题描述】:

我有两个 JPA 实体

class A{
    @OneToMany
    Lis<B> entitiesB;
    @Column("STATUS")
    String status;// will sort based on this column
}

class B{
    @ManyToOne
    A entityA;
    @Column("PROPERTY_ONE")
    String propertyOne;
    ....
    @Column("PROPERTY_M")
    String propertyM;
    ....
}

我需要将 A 与 B 左连接,然后对 B 中的列执行过滤。我有以下条件:

Join<A, B>root=criteriaBuilder
.createQuery(A.class)
.from(A.class)
.join("entitiesB");

CriteriaQuery<A> query = criteriaBuilder.createQuery(A.class);

query.select(query.from(A.class).join("entitiesB"))
        .distinct(true)
        .where(formWhereClause(filters))
        .orderBy(formOrderByClause());

如何通过A实体的status属性形成过滤器

criteriaBuilder.notEqual(root.get("A").get("status"), "SOME_STATUS_VALUE");

它为我生成了以下 SQL:

select distinct generatedAlias0 from A as generatedAlias1 
inner join generatedAlias1.entitiesB as generatedAlias0 
where ( generatedAlias2.A.status<>:param0 ) and ( generatedAlias2.propertyOne like :param1 ) 
order by generatedAlias2.propertyM desc

我遇到了以下异常:

    'org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.hql.internal.ast.QuerySyntaxException: 
Invalid path  generatedAlias2.A.status '

我该如何解决?我使用 Hibernate 4.3.5 作为持久性提供程序。

【问题讨论】:

    标签: java hibernate jpa


    【解决方案1】:

    CriteriaQuery 查询 = criteriaBuilder.createQuery(A.class);

    表示您要返回A 类型的实例。因此,您的 select 子句必须指定查询根,而不是像您所做的那样指定 Join 的实例:

    1. 定义查询的根,因为join 方法只能应用于RootJoin 类型的实例:

      Root<A> root = query.from(A.class);
      
    2. 定义连接 (I need to left join A with B):

      Join<A, B> b = root.join("entitiesB", JoinType.LEFT);
      
    3. 定义SELECT子句:

      query.select(root)
      .distinct(true)
      .where(formWhereClause(filters))
      .orderBy(formOrderByClause());
      
    4. 如何通过A实体的status属性形成过滤器

    形成如下:

    criteriaBuilder.notEqual(root.get("status"), "SOME_STATUS_VALUE");
    

    如果您想使用B 的属性作为过滤器,请定义它,例如:

    criteriaBuilder.equal(b.get("propertyOne"), "SOME_VALUE");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-31
      • 1970-01-01
      • 2020-11-30
      • 1970-01-01
      • 2019-04-17
      相关资源
      最近更新 更多