如何在连接多个表时使用JPA Criteria API

时间:2012-01-26 20:55:17

标签: java jpa join criteria-api

这是对此的进一步问题:

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"));

公司有地址,地址内有City-pojo和Country-Pojo。如何在JOIN中使用它?我试图用address.city引用它,但我收到了错误消息:

  

来自托管类型的属性[address.city]   [EntityTypeImpl @ 1692700229:Company [javaType:class   com.test.domain.Company描述符:   RelationalDescriptor(com.test.domain.Company - &gt;   [DatabaseTable(COMPANY)]),映射:16]]不存在。

2 个答案:

答案 0 :(得分:23)

如果您使用规范Metamodel,则可以避免此类错误。 在您的代码中,您滥用了“牙医”关键字,这可能是导致错误的原因,因为“牙医”不是公司实体中的字段。

但是,看看你在另一个问题中如何定义你的类,使用Metamodel定义join的方法是:

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

如果您想为City实体添加join

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

(假设字段cityName是您所在城市的正确字段名称。)

答案 1 :(得分:0)

同意@perissf。

我无法评论,但是符号“ Company_”是元数据类文件,其中包含模型类的所有属性名称。

我强烈建议使用元数据类,您可以使用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>