2016-09-21 16 views
1

Spring Data JPAリポジトリを使用してエンティティのリストを検索/フィルタリングする機能を実装しています。私はクエリの数を減らす(n + 1問題)と、フェッチメカニズムを使用してネストされたデータをフェッチしようとしています。Spring Data JPAリポジトリの仕様、ページネーション、条件fetch-join

私は2つのエンティティクラスがあります。

@Entity 
@Table(name = "delegations") 
public class Delegation { 

    @Id 
    @GeneratedValue(strategy = IDENTITY) 
    private Long id; 

    @ManyToOne 
    private Customer customer; 

    // more fields, getters, setters, business logic... 

} 

@Entity 
@Table(name = "customers") 
public class Customer { 

    @Id 
    @GeneratedValue(strategy = IDENTITY) 
    private Long id; 

    // more fields, getters, setters, business logic... 
} 

DTOフィルタクラス:

public class DelegationFilter { 

    private String customerName; 

    // more filters, getters, setters... 
} 

と検索/フィルタリングサービス:

public class DelegationService { 
    public Page<Delegation> findAll(DelegationFilter filter, Pageable page) { 
     Specifications<Delegation> spec = Specifications.where(
       customerLike(filter.getCustomerName()) 
     ); 
     return delegationRepository.findAll(spec, page); 
    } 

    public List<Delegation> findAll(DelegationFilter filter) { 
     Specifications<Delegation> spec = Specifications.where(
       customerLike(filter.getCustomerName()) 
     ); 
     return delegationRepository.findAll(spec); 
    } 

    private Specification<Delegation> customerLike(String customerName) { 
     return (root, query, cb) -> { 
      Join<Delegation,Customer> join = (Join) root.fetch(Delegation_.customer); 
      return cb.like(cb.lower(join.get(Customer_.name)), addWildCards(customerName.toLowerCase())); 
     }; 
    } 

    private static String addWildCards(String param) { 
     return '%' + param + '%'; 
    } 
} 
を210

問題:私はfindAll(DelegationFilter filter, Pageable page)を呼び出すと、私は例外を

を取得しています:

org.springframework.dao.InvalidDataAccessApiUsageException: 
org.hibernate.QueryException: query specified join fetching, but the owner 
of the fetched association was not present in the select list 

は、この問題を解決する方法はありますか?

findAll(DelegationFilter filter)(ページネーションのない方法は)私はJPQLのためのソリューションがあることを知っている

(偶数ページネーションで)も正常に動作します(fetchなし)のみjoinを使用して...魔法のように動作します: Spring-Data FETCH JOIN with Paging is not working しかし、私が欲しいです...基準のAPIに固執する

私は春ブーツ1.4(春4.3.2、春・データ-JPA 1.10.2)を使用していると私は同じ問題に直面していた5.0.9

答えて

1

を休止し、私は回避策を見つけました(source)。

クエリの戻り値の型を実行時に確認することができます。したがって、Long(countクエリが返す型)の場合は結合し、そうでなければフェッチします。あなたのコードでは、次のようになります:

... 
private Specification<Delegation> customerLike(String customerName) { 
    return (root, query, cb) -> { 
     if (query.getResultType() != Long.class && query.getResultType() != long.class) { 
      Join<Delegation,Customer> join = (Join) root.fetch(Delegation_.customer); 
     } else { 
      Join<Delegation,Customer> join = root.join(Delegation_.customer); 
     } 
     return cb.like(cb.lower(join.get(Customer_.name)), addWildCards(customerName.toLowerCase())); 
    }; 
} 
... 

私はそれが非常にきれいではないことを知っていますが、私はofund ATMを唯一の解決策です。

+0

見た目が醜い:)しかし、解決策のようです...ありがとう:) –

関連する問題