2016-11-23 11 views
3

これは、サブグループを指し、簡単なProductエンティティである:@ElementCollectionマップの関連テーブルを取得する方法

public class Product implements Comparable<Product> { 
    ...  
    @ManyToOne(optional=false, fetch=FetchType.LAZY) 
    @NotNull 
    private ProductSubGroup productSubGroup; 
    ... 
} 

私は別のエンティティでProduct年代を含むマップを持っている:

public class FinishedProduct { 
    ... 
    @NotNull 
    @ManyToOne 
    private Product product; 

    @ElementCollection(fetch=FetchType.LAZY) 
    @MapKeyJoinColumn 
    @Column(name="amount") 
    @Sort(type=SortType.NATURAL) 
    @Fetch(FetchMode.SUBSELECT) 
    private SortedMap<Product, Double> byproducts = new TreeMap<>(); 
    ... 
} 

この作品

Root<FinishedProduct> root = q.from(FinishedProduct.class); 
root.fetch("product", JoinType.LEFT); 
root.fetch("byproducts", JoinType.LEFT); 

、私はが必要になります。私はこのコードでマップをロードすることができますn + 1個の選択を生成することなく、マップに格納された副産物のうちの10個を選択する。どうすればそれらを取得できますか?ただ、例外で最終結果をフェッチ追加:

root.fetch("byproducts", JoinType.LEFT).fetch("productSubGroup", JoinType.LEFT); 

org.springframework.dao.InvalidDataAccessApiUsageException: 
Collection of values [null] cannot be source of a fetch 

はまた MapJoinと浮気しようとした、同じ例外:

MapJoin<FinishedProduct,Product,Double> map = root.joinMap("byproducts", JoinType.LEFT); 
map.fetch("productSubGroup", JoinType.LEFT); 

私は私が何とか推測マップキーを参照する必要がありますが、どのように考えている。

答えて

2

これはあなたがここにある複雑なマッピングであり、これを達成するための簡単な方法があるかどうかはわかりません。誰かがより良い答えを得られることを願っていますが、代替として、常に、永続コンテキストに事前ロードする機能があり、n + 1個の選択でフェッチされることがわかっているエンティティインスタンスがすべて存在します。

だから、あなたのクエリを発射する前に、ちょうどフェッチされることが期待されているすべてのProductSubGroup sのロード:あなたは元のクエリを持っているサブクエリでFinishedProduct上の他の追加制限を繰り返し、もちろん

select p.productSubGroup from Product p 
where p in (select index(byproducts) from FinishedProduct) 

をあなたが必要としないProductSubGroupの読み込みを避けるために。

私の意見では、の関連付けを@BatchSizeと定義することを検討してください。そうすれば、ProductSubGroupは1つずつではなくバッチでロードされます。

+0

私は何らかの理由でこのSpring Boot/Data/JPA/Hibernateの混乱の中で '@ BatchSize'を動作させることはできませんでしたが、両方とも貴重な提案です。しかし、もう一方は '@ Transactional'を呼び出し側のコントローラメソッドに追加しなければなりませんでした。 – Arthur

+0

あなたの解決策を私の他の問題、例えばhttp://stackoverflow.com/questions/40419986/hibernate-join-on-generates-invalid-queryで応用しようとしていましたが、双方向のクエリを2つの他のIDで結合すると思います。 – Arthur

+0

時々私は、Hibernateチームに、実際の使用シナリオを見つけてそれを不可能にすることが唯一の人物がいると思います。 :) – Arthur

関連する問題