🚤

【Java】Spring Data JPAのFetchableFluentQueryをSpecificationに適用してみた

に公開

概要

Spring Data JPAのFetchableFluentQueryとは、インターフェース FluentQuery.FetchableFluentQuery<T>のドキュメントにある通り、元となるクエリに対して操作を加えることができるインターフェースです。具体的には取得する件数を制限したり、結果に含めるプロパティを指定したりするなどです。
今回はSpecificationで条件を作成したクエリで、FetchableFluentQueryを使用してみたのでそのメモ書きです。

前提

  • 使用したSpring Data JPAのバージョンは3.5.0です。

実装サンプル

まずは以下のようなSpecificationを用意します。

 static Specification<TaskDefinitionEntity> specificationHasOwnerUserId(String ownerUserId, Optional<String> definitionIdOptional) {
        return (root, query, criteriaBuilder) -> {
            // LEFT JOINでcategoryを取得
            Join<TaskDefinitionEntity, TaskCategoryEntity> categoryJoin =
                    root.join("category", JoinType.LEFT);

            // 条件のリストを作成
            var predicates = new ArrayList<Predicate>();
            // 基本条件(ownerUserId)
            predicates.add(criteriaBuilder.equal(root.get("ownerUserId"), ownerUserId));
            // 条件付きでdefinitionIdの条件を追加
            if (definitionIdOptional.isPresent()) {
                predicates.add(criteriaBuilder.equal(root.get("id"), definitionIdOptional.get()));
            }

            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
    }

このSpecificationを使用する時に、FetchableFluentQueryを適用してみます。以下のように結合したテーブルのデータを取得するためプロパティ名を指定するのと、limitを設定してみます。

var specifications = TaskDefinitionRepository.specificationHasOwnerUserId(userId, Optional.empty());
// 結合したテーブルのプロパティ名を指定しデータ取得&limitを設定
var queryResult = taskDefinitionRepository.findBy(specifications, fetchable ->
                fetchable.project("category").limit(300).all());

その他参考

Discussion