春データJPA - 名前付きクエリヌルパラメータを無視して

ニコラス:

私は、次のリポジトリを持っています:

@Repository
public interface EntityRepository extends JpaRepository<Entity, Long> {

    List<Entity> findAllByFirstId(Long firstId);
    List<Entity> findAllBySecondId(Long secondId);
    List<Entity> findAllByFirstIdAndSecondId(Long firstId, Long secondId);
}

で生成されたインタフェースの実装コンストラクタio.swagger:swagger-codegen-maven-plugin用途Optional<Long>オプション要求パラメータなどを(基礎となるサービスも同じパラメータを使用して)。

ResponseEntity<List<Entity>> entities(Optional<Long> firstId, Optional<Long> secondId);

私は、パラメータに基づいて、エンティティフィルタリングしたいfirstIdsecondIdは決してありませんnullデータベースのSが、コンストラクタ(検索用のパラメータはオプションです)を通過させることができます。

ときに問題が名前付きクエリに付属しているnullパラメータはオプションであるとして渡され、JpaReposotory用途はnull、データベースの検索のための基準として。それは私が望んでいないものだ-私は無視したいであればあるほど、このパラメータに基づいてフィルタリングnull

基づいて、私の回避策ソリューションは、Optional次のとおりです。

public List<Entity> entities(Optional<Long> firstId, Optional<Long> secondId) {

    return firstId
        .or(() -> secondId)
        .map(value -> {
            if (firstId.isEmpty()) {
                return entityRepository.findAllBySecondId(value);
            }
            if (secondId.isEmpty()) {
                return entityRepository.findAllByFirstId(value);
            }
            return entityRepository.findAllByFirstIdAndSecondId(
            firstId.get(), secondId.get());
        })
        .orElse(entityRepository.findAll())
        .stream()
        .map(...)     // Mapping between DTO and entity. For sake of brevity
                      // I used the same onject Entity for both controler and repository 
                      // as long as it not related to the question   

        .collect(Collectors.toList());
}

この問題は、既に頼まれました:春データを-それはNULL値がある場合は、パラメータを無視し、作成したチケットDATAJPA-209を

限り問題は、ほぼ3歳で、チケットの日付は2012年にバックとして、私は、取り扱いのオーバーヘッドを回避するために、より快適かつ普遍的な方法が存在するかどうかお願いしたいと思いOptional、リポジトリメソッドを複製します。2つのこのようなパラメータのための解決策は、しかし、私は4-5のパラメータのために非常に同じフィルタリングを実装したいのですが、許容可能になります。

アレックスvaluiskyi:

あなたは必要とするSpecificationこのようなユーティリティクラスを

public class EntitySpecifications {
    public static Specification<Entity> firstIdEquals(Optional<Long> firstId) {// or Long firstId. It is better to avoid Optional method parameters.
        return (root, query, builder) -> 
            firstId.isPresent() ? // or firstId != null if you use Long method parameter
            builder.equal(root.get("firstId"), firstId.get()) :
            builder.conjunction(); // to ignore this clause
    }

    public static Specification<Entity> secondIdEquals(Optional<Long> secondId) {
        return (root, query, builder) -> 
            secondId.isPresent() ? 
            builder.equal(root.get("secondId"), secondId.get()) :
            builder.conjunction(); // to ignore this clause
    }
}

次に、あなたのEntityRepository拡張する必要がJpaSpecificationExecutor

@Repository
public interface EntityRepository 
    extends JpaRepository<Entity, Long>, JpaSpecificationExecutor<Entity> {

}

使用法:

@Service
public class EntityService {    

    @Autowired
    EntityRepository repository;

    public List<Entity> getEntities(Optional<Long> firstId, Optional<Long> secondId) {
        Specification<Entity> spec = 
            Specifications.where(EntitySpecifications.firstIdEquals(firstId)) //Spring Data JPA 2.0: use Specification.where
                          .and(EntitySpecifications.secondIdEquals(secondId));

        return repository.findAll(spec);        
    }
}

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=4999&siteId=1