私は、次のリポジトリを持っています:
@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);
私は、パラメータに基づいて、エンティティフィルタリングしたいfirstId
とsecondId
は決してありません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のパラメータのために非常に同じフィルタリングを実装したいのですが、許容可能になります。
あなたは必要とする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);
}
}