web-dev-qa-db-ja.com

多くのテーブルを結合するときにJPA Criteria APIを使用する方法

これはこれに対するさらなる質問です:

JOINでJPA基準APIを使用する方法

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]]は存在しません。

11
Sami

正規の Metamodel を使用すると、この種のエラーを回避できます。 「歯科医」は会社エンティティのフィールドではないため、コードで「歯科医」キーワードを誤用している可能性があります。これがおそらくエラーの原因です。

ただし、他の質問でクラスを定義した方法を見ると、Metamodelを使用してそのjoinを定義する方法は次のとおりです。

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

ご覧のとおり、メタモデルは文字列の使用を回避しているため、多くの実行時エラーを回避しています。とにかくメタモデルを使用しない場合は、これを試してください:

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があなたの都市の正しいフィールド名であると仮定します)。

25
perissf

@perissfに同意します。

コメントはできませんが、シンボル「Company_」は、モデルクラスのすべての属性名を含むメタデータクラスファイルです。

メタデータクラスを使用することを強くお勧めします。構成のプロセッサとしてorg.hibernate.jpamodelgen.JPAMetaModelEntityProcessorを使用して、Mavenプロセッサプラグインを使用してメタデータクラスを自動生成できます。

次の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>
0
aldroid