2014-05-11 2 views
-1
SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory(); 
     Session session = sessionFactory.openSession(); // create session object 
     session.beginTransaction(); // start transaction object 
     session.save(user); // save the user to database 
     session.getTransaction().commit(); // commit the transaction 
     session.close(); // closing session 

     session = sessionFactory.openSession(); 
     user = null; 
     user = (UserDetails) session.get(UserDetails.class, 1); 
     System.out.println(user.getLisOfAddresses().size()); 
    } 
} 

출력 : 봐주의 완전히 출력은 하나의 사용자이며 우리가 getListOfAddresses()를 호출 할 때 다른 주소 테이블을위한 두 가지 선택 쿼리가 있습니다;게으른 로딩은

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version). 
log4j:WARN Please initialize the log4j system properly. 
Hibernate: insert into USER_DETAIL (USER_NAME) values (?) 
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?) 
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?) 
Hibernate: select userdetail0_.USER_ID as USER1_0_0_, userdetail0_.USER_NAME as USER2_0_0_ from USER_DETAIL userdetail0_ where userdetail0_.USER_ID=? 
Hibernate: select lisofaddre0_.USER_ID as USER1_0_, lisofaddre0_.CITY_NAME as CITY2_0_, lisofaddre0_.PIN_CODE as PIN3_0_, lisofaddre0_.STATE_NAME as STATE4_0_, lisofaddre0_.STREET_NAME as STREET5_0_ from USER_ADDRESS lisofaddre0_ where lisofaddre0_.USER_ID=? 
2 

이제 프록시 개체를 확인하기 위해이 클래스 파일을 몇 줄의 코드로 변경합니다. getListOfAddresses() 메서드를 호출하기 전에 세션을 닫으면 예외가 발생합니다.

  session = sessionFactory.openSession(); // again create another session object 
     user = null; 
     user = (UserDetails) session.get(UserDetails.class, 1); 
      session.close(); // close the session before calling collection getter 
     System.out.println(user.getLisOfAddresses().size()); 

지금 출력 :

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version). 
log4j:WARN Please initialize the log4j system properly. 
Hibernate: insert into USER_DETAIL (USER_NAME) values (?) 
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?) 
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?) 
Hibernate: select userdetail0_.USER_ID as USER1_0_0_, userdetail0_.USER_NAME as USER2_0_0_ from USER_DETAIL userdetail0_ where userdetail0_.USER_ID=? 
Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.sdnext.hibernate.tutorial.dto.UserDetails.lisOfAddresses, 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.readSize(AbstractPersistentCollection.java:119) 
    at org.hibernate.collection.PersistentBag.size(PersistentBag.java:248) 
    at com.sdnext.hibernate.tutorial.HibernateTestDemo.main(HibernateTestDemo.java:48) 
우리가 객체를 가져 오는의 LAZY 유형 전략을 사용하는 경우 세션을 최대 절전 모드 때문에 코드 실패 실행 이상으로

프록시 개체를 반환, 그것은 세션에 존재 우리가 세션을 닫으면, 느슨한 로딩이 일어나지 않습니다.

SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory(); 
     Session session = sessionFactory.openSession(); 
     session.beginTransaction(); 
     session.save(user); 
     session.getTransaction().commit(); 
     session.close(); 

     session = sessionFactory.openSession(); 
     user = null; 
     user = (UserDetails) session.get(UserDetails.class, 1); 
     session.close(); //closing the session before calling collection getter 
     System.out.println(user.getLisOfAddresses().size()); 
     } 
} 

OUTPUT : 열망 가져 오기 위해

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version). 
log4j:WARN Please initialize the log4j system properly. 
Hibernate: insert into USER_DETAIL (USER_NAME) values (?) 
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?) 
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?) 
Hibernate: select userdetail0_.USER_ID as USER1_0_0_, userdetail0_.USER_NAME as USER2_0_0_, lisofaddre1_.USER_ID as USER1_2_, lisofaddre1_.CITY_NAME as CITY2_2_, lisofaddre1_.PIN_CODE as PIN3_2_, lisofaddre1_.STATE_NAME as STATE4_2_, lisofaddre1_.STREET_NAME as STREET5_2_ from USER_DETAIL userdetail0_ left outer join USER_ADDRESS lisofaddre1_ on userdetail0_.USER_ID=lisofaddre1_.USER_ID where userdetail0_.USER_ID=? 

2 ************************* *************************************************** *** 이 전략 세션에서 EAGER 가져 오기 전략을 사용하고 있으므로이 코드가 성공적으로 실행되고 있는지 확인하십시오. 메모리에로드 할 때 모든 필드가있는 원래 개체가 초기화됩니다. 위 출력 문자열에는 join 절이있는 select 문이 하나만 있습니다.

난 그냥

System.out.println(user.getLisOfAddresses().size()); 

가 FINE 실행하는에도 명시 적으로 세션을 닫은 후 알고 싶은. 위산자가 위의 컬렉션을로드하는 곳에서 가져온 것입니다. 첫 번째 레벨 캐시에서 왔습니다. EAGER FETCHING에서 세션이 닫힌 후에도 객체가 남아 있습니까? (종속 객체도로드가되는지 압니까?) LAZY LOAD가있는 케이스는 무엇입니까? 컬렉션이로드되지 않기 때문에, IT는 세션을 닫은 후 세션이 닫히고 게터가 호출 된 후

System.out.println(user.getLisOfAddresses().size()); 

게으른 로딩 오류를 보여줍니다 바로이 이유인가? 이 사람이 어떤 사람을 나타 냅니까? 나는 라지와 에거 (Eager) 채취 란 무엇을 알고 있습니까?

답변

1

한 가지 질문에 너무 많은 질문이 있습니다. 글쎄, 최대 절전 모드는 당신이 정확히 무엇을 할 것인지를 요구하고 있습니다. getload의 차이점을 알아야합니다. 당신이 얻을 때, Hibernate는 DB로부터 객체를 얻고 객체를 얻는다. 당신이 load 할 때 Hibernate는 객체를 만들고, 당신이 정말로 그것을 필요로 할 때까지 객체를로드하지 않을 것이다.

I JUST WISH TO KNOW THAT EVEN AFTER CLOSING THE SESSION EXPLICITLY, 

System.out.println(user.getLisOfAddresses().size()); 

EXECUTES FINE. 

예는, 세션을 닫으면, null로 (DB 객체에서 읽기)하여 초기화가되지 않습니다 않는 대신 이러한 개체 detached이 있습니다.절전 모드에서 분리 된 내용을 확인하십시오. 그러나 객체 자체는 GC가 휴지통에이를 때까지 남아 있습니다.

`SINCE THE COLLECTION IS NOT LOADED, IS IT THIS VERY REASON THAT 

System.out.println(user.getLisOfAddresses().size()); 

SHOWS ERROR IN LAZY LOADING AFTER SESSION IS CLOSED AND GETTER IS CALLED AFTER CLOSING THE SESSION 

이것은 분리 된 개체 + 지연로드의 이유입니다. LisOfAddresses이로드되지 않고 user 개체가 분리됩니다 (이는 최대 절전 모드 세션에 연결되지 않음을 의미). 그래서 당신의 경우 틀린 잘못된 최대 절전 세션에 user 개체가 붙어있는 것으로 가정하고 db가 맞으려고하는 프록시가 있고, 틀린 것은 실패합니다.

관련 문제