Hibernate LazyLoading без сессии

У меня есть два jsps, пытающиеся получить доступ к этой подпрограмме базы данных (через класс действий). Когда у меня нет рутины try/catch/finally и нет транзакции передачи или закрытия сессии, тогда я могу получить результаты, но только в первый раз. Когда следующий JSP пытается получить к ним доступ, я получаю nested transactions not supported потому что я не закрывал сессию.

Когда я закрываю сессию, как session.close() я получаю session was already closed error, Когда я использую HibernateUtil.close() (потому что я прочитал, я должен закрыть threadLocale) я получаю LazyInitializationException: could not initialize proxy - no Session,

Нужно ли сохранять / сохранять список после первого попадания в БД? Или сменить ленивую на энергичную загрузку? Даже прочитав о них, я не до конца понимаю, как они применяются к этому экземпляру, и не знаю точно, как указать eager загрузка, если мне нужно. Я видел использование этой аннотации fetch = FetchType.LAZY но как я могу использовать теги сопоставления, чтобы указать нетерпеливый?

DAO Transaction

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, они скажут, что если вы позвоните session.openSession(); Вы должны закрыть сеанс вручную в блоке finally.

Для решения проблемы, связанной с отложенными свойствами, вы должны извлекать отложенные свойства в сеансе, т. Е. Когда транзакция открыта / непосредственно перед закрытием сеанса. В вашем случае до вызова commit(). Если вы вызовете ленивые свойства после того, как этот код был выполнен, вы получите эту ошибку.

Чтобы избежать этой проблемы, я обычно пишу несколько служб (для одного и того же родительского объекта), чтобы загрузить разные ленивые элементы родительского объекта и закрыть сеанс. Или вы можете установить тип выборки в eager,

Другие вопросы по тегам