복붙노트

[SPRING] 봄, 최대 절전 모드 - 다 대다 - LazyInitializationException

SPRING

봄, 최대 절전 모드 - 다 대다 - LazyInitializationException

나는 2 개의 모델을 가지고있다.

사용자:

    @Entity
public class User implements Serializable {
    Long id;
    String name;
    List<Car> cars;
    public User() {

    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<Car> getCars() {
        return cars;
    }
    public void setCars(List<Car> cars) {
        this.cars = cars;
    }
}

차:

@Entity
public class Car implements Serializable {
Long id;
String mark;
public Car() {

}
public Long getId() {
    return id;
}
public void setId(Long id) {
    this.id = id;
}
public String getMark() {
    return mark;
}
public void setMark(String mark) {
    this.mark = mark;
}
}

파일 매핑 :

사용자:

    <hibernate-mapping>
<class name="com.bontade.phone_book.mvc.spring.models.User" table="USERS">
    <id name="id" type="java.lang.Long">
    <column name="ID" />
    <generator class="identity" />
    </id>        
    <property name="name" not-null="true" length="100" type="java.lang.String">
    <column name="NAME" />
    </property>       
    <list name="cars" table="USER_CAR" cascade="all">
    <key>
        <column name="USER_ID" />
    </key>
    <list-index></list-index>
    <many-to-many column="CAR_ID" class="com.bontade.phone_book.mvc.spring.models.Car" />
    </list>        
</class>
</hibernate-mapping>

차:

    <hibernate-mapping>
<class name="com.bontade.phone_book.mvc.spring.models.Car" table="CARS">
    <id name="id" type="java.lang.Long">
    <column name="ID" />
    <generator class="identity" />
    </id>
    <property name="mark"  not-null="true" length="20" type="java.lang.String">
    <column name="MARK" />
    </property>     
</class>
</hibernate-mapping>

HomePageController :

public class HomePageController extends AbstractController {
private UserDAO userDAO;
private CarDAO carDAO;

@Override
protected ModelAndView handleRequestInternal(HttpServletRequest request,
        HttpServletResponse response) throws Exception {        
    Car markCar = new Car();
    markCar.setId(null);
    markCar.setMark("111");
    carDAO.saveCar(markCar);

    User mark = new User();
    mark.setId(null);
    mark.setName("mark");
    List a = new ArrayList<Car>();
    a.add(markCar);
    mark.setCars(a);
    userDAO.saveUser(mark);
    List<User> users = userDAO.getAll();
    System.out.println("==" + users.size() + "===");
    System.out.println(users.get(0).getCars().get(0).getMark());

    ...
}
...
}

하지만 내가 줄을 실행할 때 :

System.out.println(users.get(0).getCars().get(0).getMark());

다음과 같은 스택 추적 오류가 발생했습니다.

        Hibernate: select user0_.ID as ID0_, user0_.NAME as NAME0_ from USERS user0_
==1==
2011-02-23 17:35:10 org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/PhoneBook] threw exception [Request processing failed; nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.bontade.phone_book.mvc.spring.models.User.cars, no session or session was closed] with root cause
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.bontade.phone_book.mvc.spring.models.User.cars, no session or session was closed
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372)
    at org.hibernate.collection.AbstractPersistentCollection.readElementByIndex(AbstractPersistentCollection.java:173)
    at org.hibernate.collection.PersistentList.get(PersistentList.java:293)
    at com.bontade.phone_book.mvc.spring.controllers.HomePageController.handleRequestInternal(HomePageController.java:59)
    at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
    at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:807)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:306)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:96)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:244)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:108)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:558)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:379)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:259)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:281)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)

생성 된 매핑 파일, 특히 다 대 다 관계를 잘못 작성 했습니까?

해결법

  1. ==============================

    1.기본적으로 Hibernate는 lazy load collection을로드 할 것이다. 즉, 절대적으로 필요하기 전까지는 자동차 목록을 검색하기 위해 데이터베이스로 이동하지 않습니다. 즉, DAO 레이어에서 반환 된 객체는 액세스하려고 할 때까지 자동차 목록이 초기화되지 않습니다. 액세스하려고하면 더 이상 세션 내에 있지 않으므로 예외가 발생합니다.

    기본적으로 Hibernate는 lazy load collection을로드 할 것이다. 즉, 절대적으로 필요하기 전까지는 자동차 목록을 검색하기 위해 데이터베이스로 이동하지 않습니다. 즉, DAO 레이어에서 반환 된 객체는 액세스하려고 할 때까지 자동차 목록이 초기화되지 않습니다. 액세스하려고하면 더 이상 세션 내에 있지 않으므로 예외가 발생합니다.

    명시 적으로 해당리스트 프로퍼티에서 lazy = "false"를 설정함으로써 lazy 페칭을 사용 불가능하게 할 수 있습니다. 이것은 hibernate 맵핑에서 dao 계층에서 리턴되기 전에 전체 특성이 채워지는지 확인합니다.

  2. from https://stackoverflow.com/questions/5095559/spring-hibernate-many-to-many-lazyinitializationexception by cc-by-sa and MIT license