web-dev-qa-db-ja.com

Spring Data JPA findOne()のオプションへの変更これの使用方法

SpringBoot2.0Java8を学習しています。

そして、いくつかのブログ作成チュートリアルの例に従いました。

チュートリアルのソースコードは次のとおりです。

@GetMapping("/{id}/edit")
public String edit(@PathVariable Long id, Model model) {
  model.addAttribute("categoryDto", categoryService.findOne(id));
  return "category/edit";
}

しかし、このコードはこのエラーを投げています:

categoryService.findOne(id)

JPA findOne()メソッドをOptional< S >に変更することを考えています

それを解決する方法は?

詳細:

これはcategoryServiceメソッドです。

public Category findOne(Long id) {
  return categoryRepository.findOne(id);
}
37
Hulk Choi

少なくとも、2.0バージョン、Spring-Data-JpafindOne()を変更しました。
現在、findOne()には同じシグネチャと同じ動作がありません。
以前は、CrudRepositoryインターフェイスで次のように定義されていました。

T findOne(ID primaryKey);

ここで、CrudRepositoryにある単一のfindOne()メソッドは、QueryByExampleExecutorインターフェースで次のように定義されています。

<S extends T> Optional<S> findOne(Example<S> example);

これは、最後にSimpleJpaRepositoryインターフェイスのデフォルト実装であるCrudRepositoryによって実装されます。
このメソッドはサンプル検索によるクエリであり、置換として使用することは望ましくありません。

実際、同じAPIのメソッドは新しいAPIにまだありますが、メソッド名は変更されています。
CrudRepository インターフェイスでfindOne()からfindById()に名前が変更されました。

Optional<T> findById(ID id); 

現在、Optionalを返します。 NullPointerExceptionを防ぐのはそれほど悪くありません。

つまり、実際に呼び出すメソッドはOptional<T> findById(ID id)です。

使い方は?
学習 Optional 使用法。ここにその仕様に関する重要な情報:

Null以外の値を含む場合と含まない場合があるコンテナオブジェクト。値が存在する場合、isPresent()はtrueを返し、get()は値を返します。

OrElse()(値が存在しない場合はデフォルト値を返す)やifPresent()(値が存在する場合はコードブロックを実行する)など、含まれる値の有無に依存する追加のメソッドが提供されます。


OptionalOptional<T> findById(ID id)とともに使用する方法に関するヒント

通常、IDでエンティティを検索するときに、エンティティを返すか、取得されない場合は特定の処理を行います。

ここでは、古典的な3つの使用例を示します。

1)エンティティが見つかった場合、それを取得したい場合、デフォルト値を取得したいとします。

あなたは書くことができます:

Foo foo = repository.findById(id)
                    .orElse(new Foo());

または、意味がある場合はnullのデフォルト値を取得します(APIの変更前と同じ動作):

Foo foo = repository.findById(id)
                    .orElse(null);

2)エンティティが見つかった場合、それを返したい場合、例外をスローしたいとします。

あなたは書くことができます:

return repository.findById(id)
        .orElseThrow(() -> new EntityNotFoundException(id));

3)エンティティが見つかったかどうかに応じて(必要な例外をスローせずに)別の処理を適用するとします。

あなたは書くことができます:

Optional<Foo> fooOptional = fooRepository.findById(id);
if (fooOptional.isPresent()){
    Foo foo = fooOptional.get();
   // processing with foo ...
}
else{
   // alternative processing....
}
102
davidxxx

メソッドはfindById(…)に名前が変更され、Optionalを返すため、自分で不在を処理する必要があります。

Optional<Foo> result = repository.findById(…);

result.ifPresent(it -> …); // do something with the value if present
result.map(it -> …); // map the value if present
Foo foo = result.orElse(null); // if you want to continue just like before
6
Oliver Drotbohm

Optional apiは、値を取得するためのメソッドを提供します。 isPresent()で値の存在を確認してからget()を呼び出すか、get()でチェーンされたorElse()を呼び出してデフォルト値を指定できます。

最後に試すことができるのは、カスタムメソッドで@Query()を使用することです。

2
Prashant

実際、Spring Dataの最新バージョンでは、findOneはオプションを返します。 Optionalからオブジェクトを取得する場合は、Optionalでget()を使用するだけです。ただし、まず最初に、リポジトリはサービスにオプションを返す必要があります。その後、サービスはオプションが空の場合を処理します。その後、サービスはオブジェクトをコントローラーに返す必要があります。

0
Claudiu Guja

私は常にデフォルトのメソッド"findByIdOrError"を広く使用されているCrudRepositoryリポジトリ/インターフェースで記述します。

@Repository 
public interface RequestRepository extends CrudRepository<Request, Integer> {

    default Request findByIdOrError(Integer id) {
        return findById(id).orElseThrow(EntityNotFoundException::new);
    } 
}
0
147.3k