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")