Как использовать JPA Criteria API при объединении множества таблиц

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

Как использовать JPA Criteria API в 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:Company [javaType: class com.test.domain.Company descriptor: RelationalDescriptor(com.test.domain.Company --> [DatabaseTable(COMPANY)]), отображения: 16]] нет.


person Sami    schedule 26.01.2012    source источник


Ответы (2)


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

Однако, глядя на то, как вы определили свой класс в другом вопросе, способ определить этот 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 является правильным названием поля для вашего города).

person perissf    schedule 26.01.2012
comment
Откуда взялся символ Company_ с подчеркиванием в конце? Когда я пробую это, я получаю Невозможно разрешить символ «Компания_» - person slashdottir; 12.04.2019
comment
Мне неудобно редактировать, потому что я недостаточно знаю предмет, но во второй строке кода вы имели в виду правильно использовать joinSet()? SetJoin‹Company,Product› products = companyRoot.joinSet(products); - person White_King; 15.02.2021
comment
@White_King Я думаю, обе версии должны работать, не так ли? - person perissf; 15.02.2021

Согласен с @perissf.

Я не могу комментировать, но символ «Компания_» — это файл класса метаданных, который содержит все имена атрибутов класса модели.

Я настоятельно рекомендую использовать классы метаданных, вы можете автоматически генерировать классы метаданных с помощью плагина процессора maven, используя org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor в качестве процессора в вашей конфигурации.

Этот пример плагина pom xml должен работать:

  <plugin>
                <groupId>org.bsc.maven</groupId>
                <artifactId>maven-processor-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <phase>generate-sources</phase>
                        <configuration>
                            <processors>
                                <processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
                            </processors>
                        </configuration>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>org.hibernate.orm</groupId>
                        <artifactId>hibernate-jpamodelgen</artifactId>
                        <version>${version.hibernate-jpamodelgen}</version>
                    </dependency>
                </dependencies>
            </plugin>
person aldroid    schedule 31.01.2020