2016-09-23 5 views
1

のためのクエリを作成し、私は私がそれらの間の結合を持つシンプルな2つのJPAエンティティがあります。春JPAは、効率性を参加 - 各反復

プライマリエンティティ

public class Country implements Serializable { 

    @Id 
    @Column(name = "MCC") 
    private String mcc; 

    ...... 

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
    @JoinColumn(name = "mcc", referencedColumnName = "mcc") 
    private List<CountryInfo> countryInfo; 

共同事業体CountryInfoを

public class CountryInfo implements Serializable { 

    @Id 
    @Column(name = "id") 
    private Long id; 

    @Column(name = "mcc") 
    private String mcc; 

    @Column(name = "continent") 
    private String continent; 

クエリをダンプするように構成をオンにしたときxecuted、私はこれがかなり以来、登録しようと1つのコールを作成するよりも明らかに遅いです

..見つかった各のために、別のコールが指定されたMCCとCountryInfoエンティティで行われることに気付きました、それはありますN + 1回のクエリを実行します(N =カウントは)。

は、私はすでにこのチュートリアルhttps://zeroturnaround.com/rebellabs/how-to-use-jpa-correctly-to-avoid-complaints-of-a-slow-application/を見て、それに応じて変化しますが、それはまだN + 1つのクエリを呼び出してきました。..

はこれを克服する方法はありますか?その後、

@RepositoryRestResource(exported = false) 
public interface CountryRepository extends JpaRepository<E212MCC, Long>, 
     JpaSpecificationExecutor<E212MCC> { 
} 

そして、いくつかの仕様を呼び出します:

List<E212MCC> countries = this.countryRepository.findAll(specifications); 
+0

どのようにあなたの国のインスタンスを選択している、とあなたは参加フェッチを使用して試してみましたcountryInfo関係のクエリでは? – Chris

+0

@Chrisデータがどのようにロードされているかを表示するために私の質問が更新されました。いいえFetch Joinを使って試したことがありません。 – cgval

答えて

1

をごので

データを取得するために

EDIT

私はリポジトリを持っていますを使用しています

private Specification<Country> joinContryInfo() { 
    return (root, query, cb) -> { 
     root.fetch(Country_.countryInfo); 
     // here you can fetch more entities if you need... 
     return null; 
    }; 
} 

そして、ちょうどあなたの仕様オブジェクトに追加します。:

Specifications.where(joinCountryInfo()) 

場合は、(私はあなたがJPAのメタモデルを使用していると仮定しています)操作に参加フェッチ実行仕様と試みることができるメタモデルを使用していない場合はCountry_.countryInfo"countryInfo"文字列に置き換えてください。

あなたは検索用CountryInfoフィールドを使用している場合、あなたはjoinContryInfo()指定を省略して1つの仕様に参加して、検索クエリ準備することができますが:

private Specification<Country> continentEqual(String param) { 
    return (root, query, cb) -> { 
     Join<Country,CountryInfo> join = (Join) root.fetch(Country_.countryInfo); 
     return cb.equal(join.get(CountryInfo_.continent), addWildCards(param));; 
    }; 
}