Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use JPA Criteria API when joining many tables

This is the further question to this:

How to use JPA Criteria API in JOIN

CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();

CriteriaQuery<Company> criteria = criteriaBuilder.createQuery( Company.class );
Root<Company> companyRoot = criteria.from( Company.class );
Join<Company,Product> products = companyRoot.join("dentist");
Join<Company, City> cityJoin = companyRoot.join("address.city");//Company->Address->City-city
criteria.where(criteriaBuilder.equal(products.get("category"), "dentist"),      criteriaBuilder.equal(cityJoin.get("city"),"Leeds"));

A company has an address, inside the address there is City-pojo and Country-Pojo. How can I use it in JOIN? I tried to reference it with address.city but I got the error message:

The attribute [address.city] from the managed type [EntityTypeImpl@1692700229:Company [ javaType: class com.test.domain.Company descriptor: RelationalDescriptor(com.test.domain.Company --> [DatabaseTable(COMPANY)]), mappings: 16]] is not present.

like image 799
Sami Avatar asked Jan 26 '12 20:01

Sami


1 Answers

If you use canonical Metamodel, you'll avoid this kind of errors. In your code you have misused the "dentist" keyword, that's probably the cause of your error, because "dentist" is not a field in Company entity.

However, looking at how you defined your class in the other question, the way to define that join using Metamodel is this:

SetJoin<Company,Product> products = companyRoot.join(Company_.products); 

As you can see, Metamodel avoids the use of strings, and so avoids a lot of runtime errors. If anyway you don't use Metamodel, try this:

SetJoin<Company,Product> products = companyRoot.join("products"); 

If you now want to add a predicate, i.e. something after the where, you'll write something like:

Predicate predicate = criteriaBuilder.equal(products.get(Product_.category), "dentist");
criteria.where(predicate);

If you want to add a join for the City entity:

Join<Company, City> city = companyRoot.join(Company_.city);
predicate = criteriaBuilder.and(predicate, criteriaBuilder.equal(city.get(City_.cityName), "Leeds");
criteria.where(predicate);

(supposing that the field cityName is the correct field name for your city).

like image 197
perissf Avatar answered Sep 19 '22 10:09

perissf