JPAのダーティチェックとは
JPAには、Entityの変更を自動で検知する「ダーティチェック(Dirty Checking)」という仕組みがあります。
※ ダーティチェックによる自動更新を利用するには、通常@Transactionalが必要です。
例えば、以下のようにEntityを取得します。
@Transactional
public void update(Long id) {
User user = repository.findById(id)
.orElseThrow();
user.setName("Taro");
}
Repositoryから取得したEntityは、JPAの管理対象になります。
その後、Entityの値を変更すると、
user.setName("Taro");
JPAは取得時の状態と現在の状態を比較し、変更があったことを検知します。
- Entityを取得
- JPAがEntityを管理
- Entityの値を変更
- 変更を検知
この変更検知の仕組みをダーティチェックと呼びます。
そのため、開発者が更新処理を明示的に記述しなくても、
JPAが変更内容をデータベースへ反映できます。
なぜsave()なしでUPDATEされるのか
ダーティチェックによって変更が検知されると、トランザクション終了時にJPAが自動でUPDATE文を発行します。
そのため、取得したEntityを更新する場合は、明示的にsave()を呼ばなくても変更内容がデータベースへ反映されます。
save()が必要なケース
save()が必要なのは、新しくEntityを作成する場合です。
User user = new User();
user.setName("Taro");
userRepository.save(user);
一方、Repositoryから取得したEntityの更新は、ダーティチェックによって自動的に反映されます。
- 新規作成 →
save()が必要 -
@Transactional内で取得したEntityの更新 →save()不要
まとめ
JPAには、Entityの変更を自動で検知するダーティチェックという仕組みがあります。
そのため、@Transactional内で取得したEntityの更新ではsave()は不要で、新規作成時のみsave()が必要です。