1. ホーム

[解決済み] Spring-data-jpaを使用してエンティティを更新するにはどうすればよいですか?

2022-04-04 18:22:33

質問

さて、この質問がすべてを物語っています。JPARepositoryを使用して、どのようにエンティティを更新するのですか?

JPARepositoryには 保存 メソッドで、それが実際に作成なのか更新なのかがわかりません。例えば、3つのフィールドを持つ単純なオブジェクトをUserデータベースに挿入してみます。 firstname , lastnameage :

 @Entity
 public class User {

  private String firstname;
  private String lastname;
  //Setters and getters for age omitted, but they are the same as with firstname and lastname.
  private int age;

  @Column
  public String getFirstname() {
    return firstname;
  }
  public void setFirstname(String firstname) {
    this.firstname = firstname;
  }

  @Column
  public String getLastname() {
    return lastname;
  }
  public void setLastname(String lastname) {
    this.lastname = lastname;
  }

  private long userId;

  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  public long getUserId(){
    return this.userId;
  }

  public void setUserId(long userId){
    this.userId = userId;
  }
}

そして、単純に save() この時点で、実際にはデータベースへの挿入が行われています。

 User user1 = new User();
 user1.setFirstname("john"); user1.setLastname("dew");
 user1.setAge(16);

 userService.saveUser(user1);// This call is actually using the JPARepository: userRepository.save(user);

ここまでは順調です。さて、このユーザーを更新したい、例えば年齢を変更したい。この目的のために、私はQueryDSLやNamedQueryなどのクエリを使用することができます。しかし、私はspring-data-jpaとJPARepositoryを使いたいだけだと考えると、挿入の代わりに更新を行いたいことをどのように伝えればいいのでしょうか?

具体的には、spring-data-jpaに、ユーザー名とfirstnameが同じユーザーは実際にはequalであり、既存のエンティティは更新されるはずであると、どのように伝えればいいのでしょうか。equalsをオーバーライドしても、この問題は解決されませんでした。

どのように解決するのですか?

エンティティのアイデンティティは、プライマリキーによって定義されます。そのため firstnamelastname が主キーの一部でない場合、JPAに対して User と同じ firstnamelastname が異なる場合は、同等として扱われます。 userId s.

ですから、もしあなたが User で識別される。 firstnamelastname を見つける必要があります。 User をクエリで実行し、見つかったオブジェクトの適切なフィールドを変更します。これらの変更は、トランザクションの終了時に自動的にデータベースに反映されるので、明示的に変更を保存する必要はありません。

EDITです。

JPAの全体的なセマンティクスについて詳しく説明すべきかもしれません。永続化APIの設計には、主に2つのアプローチがあります。

  • 挿入/更新の方法 . データベースを変更する必要がある場合、永続化APIのメソッドを明示的に呼び出す必要があります。 insert でオブジェクトを挿入したり update で、オブジェクトの新しい状態をデータベースに保存します。

  • ユニット・オブ・ワークの考え方 . この場合、オブジェクトのセットを持っています。 マネージド 永続化ライブラリによって これらのオブジェクトに加えたすべての変更は、作業単位の終了時(つまり、典型的なケースでは現在のトランザクションの終了時)に自動的にデータベースにフラッシュされます。データベースに新しいレコードを挿入する必要がある場合、対応するオブジェクトを作成します マネージド . マネージド オブジェクトは主キーで識別されるので、主キーがあらかじめ定義されたオブジェクトを作ると マネージド このオブジェクトは、同じIDのデータベースレコードと関連付けられ、このオブジェクトの状態が自動的にそのレコードに伝搬されます。

JPAでは後者のアプローチをとっています。 save() は、Spring Data JPA のバックグランドを merge() は、プレーンなJPAでは、エンティティが マネージド というように つまり save() は、定義済みの ID を持つオブジェクトに対して、 新しいレコードを挿入するのではなく、対応するデータベースのレコードを更新します。 save() とは呼ばれません。 create() .