TroubleShooting

org.springframework.dao.InvalidDataAccessApiUsageException

에디개발자 2020. 12. 5. 07:00
반응형

오늘도 어김없이 등장하는 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를 사용할 수 있습니다.

 

 

 

반응형