org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.timcook.capstone.domain.Village.devices, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:614)
.
.
.
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) ~[tomcat-embed-core-9.0.62.jar:9.0.62]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-embed-core-9.0.62.jar:9.0.62]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.62.jar:9.0.62]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890) ~[tomcat-embed-core-9.0.62.jar:9.0.62]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743) ~[tomcat-embed-core-9.0.62.jar:9.0.62]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.62.jar:9.0.62]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.62.jar:9.0.62]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.62.jar:9.0.62]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.62.jar:9.0.62]
at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
프로젝트를 진행 중 LazyInitializationException
가 발생했다.
@Entity
@Getter
@NoArgsConstructor
public class Village {
// 코드 생략
@OneToMany(mappedBy = "village")
private List<Device> devices = new ArrayList<>();
}
@Getter
@Entity
@NoArgsConstructor
public class Device {
// 코드 생략
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "VILLAGE_ID")
private Village village;
}
Village
와Device
도메인으로, 일대다 양방향 연관관계를 맺고 있었다.
문제가 발생한 메서드는 findAllDevices
로, /villages/{id}/devices
로 요청이 들어오면 Village
와 연결된 모든 Device
를 가져오는 작업을 한다.
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.timcook.capstone.domain.Village.devices, could not initialize proxy - no Session
위 에러는 VillageService
에서 Village
조회에 성공한 후 연결된 Device
를 조회할 때 영속성 컨텍스트
가 종료되어 버려서 지연로딩을 할 수 없어서 생기는 에러다. 즉, 트랜잭션 밖에서 엔티티를 조회하게 되는 상황이다.
VillageService
의 코드를 보면 @Transactional
이 선언되어 있지 않다. 그렇기 때문에 Village
를 조회 했을 경우 지연 로딩으로 연관되어 있는 Device
를 Proxy
로 가져오지 못한다. 따라서 지연 로딩 자체가 불가능한 상태다.
간단히 @Transactional
을 선언해줌으로써 해결했다.