Как использовать API-интерфейс JPA при объединении многих таблиц

Это еще один вопрос:

Как использовать 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: class com.test.domain.Компьютерный дескриптор: RelationalDescriptor (com.test.domain.Company → [DatabaseTable (COMPANY)]), сопоставлений: 16]] нет.

Ответ 1

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

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

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

Как вы можете видеть, Metamodel избегает использования строк и, таким образом, позволяет избежать большого количества ошибок во время выполнения. Если в любом случае вы не используете 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 является правильным именем поля для вашего города).