概要
とあるTBLからレコードを削除したいので、Repositoryに以下のようにユーザーIDで削除するメソッドを定義した
ちなみにプライマリーキーはユーザーIDではないので、元から用意されている deleteById
は使えない
repository.java
@Repository
public interface UserListRepository extends JpaRepository<UserEntity, Long> {
List<User> deleteByUserId(String userId);
}
そして、呼び出し元で削除を実行
service.java
@Service
public class AttachmentOwningService {
@Autowired
UserListRepository userListRepository;
public void deleteUser(String userId) {
// ユーザー削除
userListRepository.deleteByUserId(userId);
}
}
とすると、、、以下のようなエラーが発生
No EntityManager with actual transaction available for current thread - cannot reliably process 'remove' call
現在のスレッドで使用可能な実際のトランザクションを持つEntityManagerがありません-「削除」呼び出しを確実に処理できません
原因
メソッドに@Transactional
アノテーションをつけることで解決した
repository.java
@Repository
public interface UserListRepository extends JpaRepository<UserEntity, Long> {
@Transactional
List<User> deleteByUserId(String userId);
}
find
なら同じように書いても普通に動くのに、deleteだとなぜこんなことに、、、と思ったのだが、
@Transactional
は、DB トランザクション処理をよしなにやってくれる便利なやつである。
例外発生時にロールバックをしてくれたりと心強い上のだが、おそらくJPAがdeleteメソッドを自動生成する場合に@Transactional
が付いてないと弾くようにしているのだと思う
確かにdeleteする際に自前でロールバック処理を書く必要性はないしな、、と感じた