해결된 질문
작성
·
470
0
안녕하세요 항상 강의 잘 보고 있습니다.
영한님께서 알려주신 내용으로 공부와 토이프로젝트를 병행해나가다 이해가 가질 않는 부분이 있어서 질문드립니다.
A클래스에 @PostConstructor 어노테이션을 붙여 객체 a를 미리 저장해 DB에 저장을 하고 B클래스에도 @PostConstructor를 붙여 객체 b를 저장하려 하였습니다.
(A클래스와 B클래스의 연관관계는 일대다입니다.)
a객체에 b객체를 리스트 형태로 저장할 수 있게끔 빈 리스트를 만들어 저장하는 것까지 A클래스에서 확인을 하였고 B클래스에서 b객체를 만들고 아까 저장한 a객체를 DB에서 가져오는것까지 확인하였습니다.
이후 a객체와 b객체의 연관관계를 연관관계 편의 메서드로 만들어주려하였으나 a객체에서 b객체들을 담을수 있게끔 만들어둔 리스트 형식의 필드가 lazyinitializationexception 예외를 발생시키며 더미데이터 생성에 실패하였습니다.
@OneToMany의 기본 로딩 전략이 지연로딩이기에 생긴 문제인가 싶어 em.flush, @GraphEntity, hibernate.initialize까지 해보았으나 똑같이 lazyinitializationexception를 발생시키며 더미데이터 생성에 실패하였습니다.
(혹시나 해서 즉시로딩으로 변경하니 더미데이터 생성은 문제없이 잘 되었습니다.)
혹시 어떤 이유로 다음과 같은 현상이 발생했는지 알 수 있을까요?
답변 2
1
https://www.inflearn.com/questions/26902/postconstruct%EC%99%80-transactional-%EB%B6%84%EB%A6%AC
영한님이 이전에 답글남겨주신 걸 바탕으로 해결했습니다!
문제가 되는 이유는 해당 링크에서도 말씀하셨다시피 @PostConstructor는 빈 생성만을 완료한 이후 호출이 된다고 말씀하셨습니다.
저의 경우에 대입한다면 @PostConstructor안에서 지연로딩을 이용해서 리스트를 가져오려고 할 때 @Trasactional이 있더라도 트랜잭션을 처리하는 AOP적용이 되지 않습니다.
그렇기에 직접 트랜잭션을 열어서 해당 트랜잭션 내부에서 실행하니 원하는대로 @PostConstructor내부에서도 정상적으로 지연로딩이 가능했습니다!
protected PlatformTransactionManager txManager;
TransactionTemplate tmpl = new TransactionTemplate(txManager);
tmpl.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
//PUT YOUR CALL TO SERVICE HERE
}
});
++ 직접 트랜잭션을 열어도 @Trasactional 처럼 해당 메서드 안에서 호출되는 다른 메서드까지는 트랜잭션이 이어지지는 않는듯 합니다!