❕문제 상황
알림 삭제 기능을 개발하던 중 발생했다
❗️ 에러 문구
org.springframework.dao.InvalidDataAccessApiUsageException: No EntityManager with actual transaction available for current thread - cannot reliably process 'remove' call
- JPA는 영속성 컨텍스트를 통해 엔티티를 관리한다.
영속성 컨텍스트- 엔티티 객체를 1차 캐시에 저장하고, 트랜젝션이 끝날 때 데이터베이스에 반영- JPA는 트랜젝션 단위로 데이터베이스와의 작업을 처리한다.
트랜젝션이 없으면 데이터 변경작업(insert, update, delete)를 수행할 수 없다.
💡 가능한 해결 방법
//예시 코드
@PersistenceContext
private EntityManager entityManager;
public boolean deleteNotification(String notificationId) {
entityManager.getTransaction().begin();
Notification notification = entityManager.find(Notification.class, notificationId);
if (notification != null) {
entityManager.remove(notification);
entityManager.getTransaction().commit();
return true;
} else {
entityManager.getTransaction().rollback();
return false;
}
}
✅ 선택한 해결 방법
@Transactional 어노테이션 추가 방식
- Spring JPA의 표준적인 트랜잭션 관리 방식이다.
- 코드가 간결하고 직관적이며, 효율적이다.
-> notificaitonService의 deleteNotification에@Transactional을 추가한다.
//알림 삭제
@Transactional
public boolean deleteNotification(String userNickname, String notificationId) {
// 알림 조회
Optional<Notification> notification = notificationRepository.findByNotificationId(notificationId);
if (notification.isPresent() && notification.get().getReceiver().equals(userNickname)) {
// 알림이 존재, receiver와 user nickname같으면 삭제
int result = notificationRepository.deleteByNotificationId(notificationId);
if (result == 1) {
log.info("result={}", result);
return true;
} else return false;
}
// 알림이 존재하지 않는 경우
return false;
}