프로젝트/크루트

Entity에 @Transactional을 쓰고 싶은데 그래도 될까?

발전생 2022. 3. 28. 21:09

처음에 service layer에서 프로젝트 생성 시 3개의 파트를 db에 저장하고, 프로젝트 제안자는 자기 포지션에 따라 적절한 파트에 들어가도록 UserPart 테이블에도 데이터가 저장되게 했다. 

ProjectRepository를 테스트하면서 project entity 안에 이 로직(프로젝트 생성 시 파트 3개 생성, userpart 1개 생성)이 들어가면 범용성이 좋아질거 같다고 생각했다. 그래서 ProjectService에 있던 로직을 제거하고 ProjectRepositoy에 넣어봤다.

 

참고로 생성자에는 @Transactional 애노테이션을 쓸 수 없다.

@Target({ElementType.TYPE, ElementType.METHOD})

@Transactional의 타겟에 class는 없다.

그래서 @Transactional을 적용한 메소드를 만든 뒤 생성자에서 호출해줬다. 문제는 다른 클래스의 테스트 케이스에서 발견됐다. 분석해본 결과 Repository layer로 옮긴 로직이 제대로 롤백이 되지 않았다. 

 

검색을 해보았더니 @Transactional은 스프링에 의해 관리되므로 스프링에 의해 관리되는 빈에 선언해줘야 한다. Entity는 hibernate가 관리하는 빈이기 때문에 @Transactional이 적용되지 않는다. 

@Transactional을 안 써도 테스트 시 rollback에 문제가 있었다.

 

@Transactional은 repository나 service layer에서 써야 한다. service layer가 더 추천된다.

https://stackoverflow.com/questions/42838263/can-i-place-the-transactional-annotation-to-an-entity-class

 

Can I place the @Transactional annotation to an entity class?

I am trying the Active Record pattern using Spring and Hibernate framework. Below is the description of this pattern: An object carries both data and behavior. Much of this data is persistent and

stackoverflow.com