2014-05-19 3 views
0

액션 클래스를 통해이 데이터베이스 루틴에 액세스하려고하는 두 개의 JSP가 있습니다. 내가 아무 try/catch/finally 루틴 및 커밋 트랜잭션 또는 세션 닫을 때 나는 결과를 얻을 수 있지만 처음에만. 다음 jsp가 그들에게 접근을 시도 할 때 나는 세션을 닫지 않았기 때문에 nested transactions not supported을 얻는다.Hibernate LazyLoading no session

session.close()과 같은 세션을 닫으면 session was already closed error이됩니다. HibernateUtil.close()을 사용할 때 (내가 threadLocale을 닫아야한다는 것을 알기 때문에) 나는 LazyInitializationException: could not initialize proxy - no Session을 얻습니다.

첫 번째 DB 히트 이후에 목록을 저장/유지해야합니까? 또는 게으른로드에서 열심히로드로 변경 하시겠습니까? 그들에 대해 읽은 후에도, 내가이 인스턴스에 어떻게 적용되는지 완전히 이해하지 못하고 정확하게해야한다면 eager 로딩을 지정하는 방법을 정확히 알지 못합니다. 이 주석 사용법을 보았습니다 fetch = FetchType.LAZY 그러나 매핑 태그를 사용하여 열심히 지정하려면 어떻게해야합니까?

DAO 거래

public List<Flights> getflights(String departure, String destination) 
     { 

      this.session = HibernateUtil.getSessionFactory().getCurrentSession(); 

      List<Flights> flist = null; 

      if(session ==null){session = HibernateUtil.getSessionFactory().getCurrentSession();} 
      Transaction tx = session.beginTransaction(); 
      try 
      { 
       String hql = "from Flights as f Where f.destinationsByDepartureCode = :departureCode AND f.destinationsByDestinationCode = :destinationCode"; 
       Query q = session.createQuery(hql); 
       q.setParameter("departureCode", departure); 
       q.setParameter("destinationCode", destination); 
       flist = (List<Flights>) q.list(); 
       tx.commit(); 
       tx = null; 
      } 
      catch (Exception e) 
      { 
       tx.rollback(); 
       e.printStackTrace(); 
      } 
      finally{ 
    //   session.close(); 
       HibernateUtil.closeSession(); // diff to above. this closes threadlocale. 
      } 

      return flist; 
     } 

항공편 매핑

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 
<!-- Generated 07/05/2014 11:35:38 PM by Hibernate Tools 3.6.0 --> 
<hibernate-mapping> 
    <class catalog="seng3150" name="model.hibernate.Flights" table="flights"> 
    <id name="flightid" type="java.lang.Integer"> 
     <column name="flightid"/> 
     <generator class="identity"/> 
    </id> 
    <many-to-one class="model.hibernate.Destinations" fetch="select" name="destinationsByStopOverCode"> 
     <column length="3" name="StopOverCode"/> 
    </many-to-one> 
    <many-to-one class="model.hibernate.Destinations" fetch="select" name="destinationsByDestinationCode"> 
     <column length="3" name="DestinationCode" not-null="true"/> 
    </many-to-one> 
    <many-to-one class="model.hibernate.Airlines" fetch="select" name="airlines"> 
     <column length="2" name="AirlineCode" not-null="true"/> 
    </many-to-one> 
    <many-to-one class="model.hibernate.Destinations" fetch="select" name="destinationsByDepartureCode"> 
     <column length="3" name="DepartureCode" not-null="true"/> 
    </many-to-one> 
    <many-to-one class="model.hibernate.Planetype" fetch="select" name="planetype"> 
     <column length="20" name="PlaneCode" not-null="true"/> 
    </many-to-one> 
    <property name="flightNumber" type="string"> 
     <column length="6" name="FlightNumber" not-null="true"/> 
    </property> 
    <property name="departureTime" type="timestamp"> 
     <column length="19" name="DepartureTime" not-null="true"/> 
    </property> 
    <property name="arrivalTimeStopOver" type="timestamp"> 
     <column length="19" name="ArrivalTimeStopOver"/> 
    </property> 
    <property name="departureTimeStopOver" type="timestamp"> 
     <column length="19" name="DepartureTimeStopOver"/> 
    </property> 
    <property name="arrivalTime" type="timestamp"> 
     <column length="19" name="ArrivalTime" not-null="true"/> 
    </property> 
    <property name="duration" type="int"> 
     <column name="Duration" not-null="true"/> 
    </property> 
    <property name="durationSecondLeg" type="java.lang.Integer"> 
     <column name="DurationSecondLeg"/> 
    </property> 
    <set fetch="select" inverse="true" lazy="true" name="bookingses" table="bookings"> 
     <key> 
     <column name="flightid" not-null="true"/> 
     </key> 
     <one-to-many class="model.hibernate.Bookings"/> 
    </set> 
    </class> 
</hibernate-mapping> 

답변

1

session.getCurrentSession()가 자동으로 거래/세션을 닫습니다. API this을 보면 session.openSession()으로 전화하면됩니다. finally 블록에서 수동으로 세션을 닫아야합니다.

지연 등록 정보에 문제가있는 경우 트랜잭션이 열려있을 때/세션을 닫기 직전에 세션에서 지연 등록 정보를 가져와야합니다. 당신의 경우에는 commit()이 호출되기 전에. 해당 코드가 실행 된 후에 지연 등록 정보를 호출하면 해당 오류가 발생합니다.

이 문제를 피하기 위해 나는 보통 부모 개체의 여러 게으른 항목을로드하고 세션을 닫는 몇 가지 서비스 (동일한 부모 개체에 대해)를 작성합니다. 또는 가져 오기 유형을 eager으로 설정할 수 있습니다.