Skip to content
Advertisement

Java – JPA-Specification: how to create criteria/specification on a field that belongs to a nested object?

I am using jdk 1.8 , hibernate and jpa in my project. And using specification/criteria to build my search query.

I have a class A ( an hibernate entity) which has class B as an attribute. So, roughly, it looks like :

@Entity
class A {
     Long id;  
     String comment;

     @OneToOne
     B b;
}

and…

@Entity
class B {
    
     Long id;
     String type;
}


 

My repository class looks like (roughly):

public interface ARepository extends PagingAndSortingRepository<A, Integer>,
                                                                    JpaSpecificationExecutor<A> {

}

Most of the simple JPA queries are working as expected. Even the specification/criteria based directly on Class A is working. However, I need to create a dynamic query and that should be executed under “findAll” method of PagingAndSortingRepository class. This query should be equivalent to

select * from A a left join B b on a.b_id = b.id 
   where b.type='final' and a.comment='blah';

I created a similar logic as above in a specification like :

public Specification<A> getSpecification() {

return (itemRoot, query, criteriaBuilder) -> {
    .........
    List<Predicate> partialQueries = new ArrayList<>();

    partialQueries.add(criteriaBuilder.equal(itemRoot.get("b.type"), "final"));
    partialQueries.add(criteriaBuilder.equal(itemRoot.get("comment"), "blah"));

    //Other queries to be added...

    return   criteriaBuilder.and(partialQueries.toArray(new Predicate[0]));
  };
}

And getting error :

Unable to locate Attribute  with the the given name [b.type] on this ManagedType [com.something.domain.A]

Any insight on how to create criteria/specification on a field that belongs to a nested object?

Advertisement

Answer

If you want to filter nested object. You can write

itemRoot.get("NestedTableName").get("nestedfieldname")

In your case - itemRoot.get("B").get("type")
Advertisement