UL :)
UL의 개발 블로그
UL :)
전체 방문자
오늘
어제
  • 분류 전체보기 (220)
    • 일상 (1)
    • 회고록 (7)
    • ChatGPT 아카이빙 (0)
    • PS(Java) (114)
      • 백준 (37)
      • 인프런 강의 문제 (77)
    • Web (69)
      • Spring (18)
      • JPA (7)
      • JSP (9)
      • HTML5 (12)
      • CSS (19)
      • HTTP (0)
      • 보안 (2)
    • Language (5)
      • Java (3)
      • JS (1)
      • Python (1)
    • Git, GitHub (4)
    • Settings (18)
      • IntelliJ (7)
      • Eclipse (2)
      • VSCode (3)
      • Android Studio (1)
      • VMware (2)
      • Mac (0)
    • Etc (1)

블로그 메뉴

  • 홈
  • 태그

공지사항

인기 글

태그

  • ViewName반환
  • 요청헤더
  • 1차 캐시
  • 백준
  • @GetMapping
  • produces
  • TABLE 전략
  • ReturnValueHandler
  • ORM
  • @Table
  • @JoinColumn
  • @PostMapping
  • argumentresolver
  • 영속성
  • HandlerMethodArgumentResolver
  • @Column
  • @ManyToOne
  • HttpMessageConverter
  • 엔티티 매핑
  • BOJ
  • @RequestParam
  • SEQUENCE 전략
  • @Id
  • 영속성컨텍스트
  • 동일성보장
  • consumes
  • 정렬
  • JPA
  • IDENTITY 전략
  • EntityManagerFactory

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
UL :)

UL의 개발 블로그

테스트용 더미 데이터 넣기 (no entitymanager with actual transaction available for current thread)
Web/Spring

테스트용 더미 데이터 넣기 (no entitymanager with actual transaction available for current thread)

2022. 8. 9. 02:23

문제원인

 

빈 생명주기 콜백 메서드를 사용해서 더미 데이터를 DB에 넣으려고 하니 에러가 뜬다.

 

no entitymanager with actual transaction available for current thread

 

구글링을 해보니 @PostConstruct에는 직접적으로 @Transactional을 적용할 수 없다고 한다.

그래서 인프런 커뮤니티에 달린 글을 찾아봤는데 찾은 내용이 다음과 같다.

 

 

 

 

 @PostConstruct는 해당 빈 자체만 생성되었다고 가정하고 호출됩니다. 해당 빈에 관련된 AOP등을 포함한, 전체 스프링 애플리케이션 컨텍스트가 초기화 된 것을 의미하지는 않습니다.

 

트랜잭션을 처리하는 AOP등은 스프링의 후 처리기(post processer)가 완전히 동작을 끝내서, 스프링 애플리케이션 컨텍스트의 초기화가 완료되어야 적용됩니다.

 

정리하면 @PostConstruct는 해당빈의 AOP 적용을 보장하지 않습니다.

 

이런 것을 우회하는 여러가지 방법이있는데요. 제가 보여드린 방법(다른 스프링 빈을 호출해서 사용하는 방법)을 포함해서, AOP를 사용하지 않고 트랜잭션을 직접 코딩하는 방법, 애플리케이션 컨텍스트가 완전히 초기화 된 이벤트를 받아서 호출하는 방법 등이 있습니다.

 

관련해서 다음 링크를 참고해보시면 더욱 자세한 도움을 받을 수 있습니다^^

https://stackoverflow.com/questions/17346679/transactional-on-postconstruct-method

 

- 김영한 선생님 (출처:https://www.inflearn.com/questions/26902)

 

 

 

해결

 

@PostConstruct는 해당빈의 AOP 적용을 보장하지 않으므로 우회해야한다.

 

해당 빈에 inner static 클래스를 생성해서 @Transactional를 붙인 메서드를 init 메서드에서 호출해야하는 방법은 이 포스팅을 참고,

 

나는 애플리케이션 컨텍스트가 완전히 초기화 된 이벤트를 받아서 호출하는 방법을 사용했다 : 참고한 포스팅

 

@Component
@RequiredArgsConstructor
public class TestDataInit {

    private final H2MemberRepository memberRepository;

    @EventListener(ApplicationReadyEvent.class)
    @Transactional
    public void initDB(){
        initTestMember();
    }

    public void initTestMember() {
        Member member1 = new Member("testid1","testpass1","테스트사용자1");
        Member member2 = new Member("testid2","testpass2","테스트사용자2");

        memberRepository.save(member1);
        memberRepository.save(member2);
    }
}

 

잘 적용된다.

 

저작자표시 비영리 변경금지 (새창열림)

'Web > Spring' 카테고리의 다른 글

DTO의 사용범위는 어디까지? 또, DTO 변환은 어디서?  (4) 2022.09.24
[Error] Update/delete queries cannot be typed  (0) 2022.09.06
검증 - 직접구현부터 Spring Validation 까지  (0) 2022.08.05
spring-boot-devtools  (0) 2022.08.04
MapStruct 적용  (0) 2022.06.08
    'Web/Spring' 카테고리의 다른 글
    • DTO의 사용범위는 어디까지? 또, DTO 변환은 어디서?
    • [Error] Update/delete queries cannot be typed
    • 검증 - 직접구현부터 Spring Validation 까지
    • spring-boot-devtools
    UL :)
    UL :)
    백엔드 개발자를 목표로 달리고 있습니다🔥

    티스토리툴바