인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

쿠헐헐헐헐님의 프로필 이미지
쿠헐헐헐헐

작성한 질문수

실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화

@PostConstruct 지정 함수 @Transactional 지정 시 컨텍스트 관리가 안되는 경우

작성

·

513

0

[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? 예
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예
3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예
 
역시 백문이 불여일타!! 강의 보고 혼자 샘플작성하다 막 터집니다. 강의 볼때는 '음~ 그렇지~' 하고 보던게 안보고 혼자 작성해보니 강사님이 말씀하시는 "이거 분명이 개발할 때 문제 발생합니다." 하는거 다 터지네요.
 

[질문 내용]
 
InitDB.java 샘플 따라하다가 궁금한점이 생겨 질문 드립니다. 애플리케이션 구동 시 초기 데이터를 넣기 위해 @PostConstruct 로 코드를 작성하는 부분에서 문제가 발생했습니다.
 
 
"Caused by: javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call"
 
결론은 영속성 관리가 안되는 문제인거 같습니다. 근데 @Transactional을 붙였고 내부 함수 호출도 아닌데 왜 관리가 안되냐해서 디버깅을 해봤습니다.
 
PostConstruct 하는 부분을 따라가 보니 해당 함수를 invoke하는 클래스가 프록시가 아니더군요. InitDB의 내부 맴버는 프록시인데.
 
 
질문: PostConstruct를 호출되는 대상 클래스도 spring container에 있는 bean같은데 왜 저넘은 프록시가 아닌거죠? 다른 bean의 맴버로 주입되는 bean만 프록시인 건가요?

답변 1

1

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. juheon.ha님

PostConstruct가 호출되는 시점은 자기 빈을 초기화 하는 시점으로 아주 빠르게 일어납니다.

따라서 트랜잭션 프록시가 아직 적용되지 않은 상태에서 이런 호출이 발생하게 됩니다.

이 문제를 해결하려면 스프링 부트 초기화 이벤트로 검색해보시면 도움이 되실꺼에요.

근본적인 해결은 아니지만 간단하게 해결하시려면 @PostConstruct, @Transactional 빈을 분리해서 호출하면 가능합니다.

감사합니다.

답변감사합니다.

결론은 호출 시점의 문제군요. 답변 주신 부분도 상세히 공부해봐야 겠습니다. Spring 공부할 께 너무 많네요. 

쿠헐헐헐헐님의 프로필 이미지
쿠헐헐헐헐

작성한 질문수

질문하기