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