Как использовать JPA Criteria API при объединении многих таблиц - PullRequest
11 голосов
/ 27 января 2012

Это еще один вопрос к этому:

Как использовать API критериев JPA в 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"));

У компании есть адрес, внутри которого находятся City-pojo и Country-Pojo. Как я могу использовать его в JOIN? Я попытался сослаться на него с address.city, но получил сообщение об ошибке:

Атрибут [address.city] из управляемого типа [EntityTypeImpl @ 1692700229: Компания [javaType: класс com.test.domain.Company дескриптор: RelationalDescriptor (com.test.domain.Company -> [DatabaseTable (COMPANY)]), сопоставления: 16]] отсутствует.

1 Ответ

23 голосов
/ 27 января 2012

Если вы используете каноническую метамодель , вы избежите такого рода ошибок. В вашем коде вы неправильно использовали ключевое слово «дантист», что, вероятно, является причиной вашей ошибки, потому что «дантист» не является полем в сущности компании.

Однако, глядя на то, как вы определили свой класс в другом вопросе, способ определить, что join, используя Метамодель, таков:

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

Как видите, Metamodel избегает использования строк и, следовательно, избегает многих ошибок во время выполнения. Если в любом случае вы не используете Метамодель, попробуйте это:

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

Если вы теперь хотите добавить predicate, то есть что-то после where, вы напишите что-то вроде:

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

Если вы хотите добавить join для объекта City:

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

(при условии, что поле cityName является правильным названием поля для вашего города).

...