0

I have two JPA entities

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

and

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

I need to left join A with B and then perform filtering on columns from B. I have the following criteria:

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());

How do I form the filter by the status property from A entity

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

It has generated me the following 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

I got the following exception:

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

How can I fix it? I am using Hibernate 4.3.5 as the persistence provider.

mr.M
  • 851
  • 6
  • 23
  • 41

1 Answers1

1

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

means that you want to return instances of type A. Therefore, your select clause must specify query root instead of an instance of Join as you did:

  1. Define the root of the query because the join method can only be applied either to an instance of Root or Join types:

    Root<A> root = query.from(A.class);
    
  2. Define Join (I need to left join A with B):

    Join<A, B> b = root.join("entitiesB", JoinType.LEFT);
    
  3. Define the SELECTclause:

    query.select(root)
    .distinct(true)
    .where(formWhereClause(filters))
    .orderBy(formOrderByClause());
    
  4. How do I form the filter by the status property from A entity

Form it as follows:

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

and if you want to use attributes of B as a filter define it, for example, as:

criteriaBuilder.equal(b.get("propertyOne"), "SOME_VALUE");
ujulu
  • 3,289
  • 2
  • 11
  • 14