반응형
오늘도 어김없이 등장하는 Exception!!
org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query
증상
Querydsl로 Update, Delete하던 중 에러가 발생하였습니다. 에러가 발생한 코드는 다음과 같습니다.
public Long deleteQuery(Long id) {
// JpaQueryFactory 사용 시
// return jpaQueryFactory.delete(store)
// .where(store.id.eq(id))
// .execute();
// QuerydslRepositorySupport 사용 시
return delete(store)
.where(store.id.eq(id))
.execute();
}
public Long updateQuery(Long id, String address) {
// JpaQueryFactory 사용 시
// return jpaQueryFactory.update(store)
// .where(store.id.eq(id))
// .execute();
// QuerydslRepositorySupport 사용 시
return update(store)
.set(store.address, address)
.where(store.id.eq(id))
.execute();
}
원인
에러 로그를 살펴보니 문제는 너무나 간단하네요. TransactionRequiredException 대충 보아도 Transaction이 Required 되지 않아서 발생하는 것입니다.
해결
update, delete하는 메서드에 @Transactional 을 붙혀줍니다. 수정된 소스는 다음과 같습니다.
@Transactional // 추가
public Long deleteQuery(Long id) {
// JpaQueryFactory 사용 시
// return jpaQueryFactory.delete(store)
// .where(store.id.eq(id))
// .execute();
// QuerydslRepositorySupport 사용 시
return delete(store)
.where(store.id.eq(id))
.execute();
}
@Transactional // 추가
public Long updateQuery(Long id, String address) {
// JpaQueryFactory 사용 시
// return jpaQueryFactory.update(store)
// .where(store.id.eq(id))
// .execute();
// QuerydslRepositorySupport 사용 시
return update(store)
.set(store.address, address)
.where(store.id.eq(id))
.execute();
}
Tip.
Querydsl로 update, delete하는 방법은 2가지가 있습니다.
첫번째 방법은 QuerydslRepositorySupport 상속받아 update() 메서드를 사용합니다.
- 내부적으로 JPAUpdateClause() 클래스를 사용합니다.
두번쨰 방법은 JpaQueryFactory를 사용할 수 있습니다.
반응형