jsky
jsky

Reputation: 2217

Hibernate LazyLoading no session

I have two jsps trying to access this database routine (via action class). When i have no try/catch/finally routine and no commiting transaction or closing of session then i can get the results but only the first time. When the next jsp tries to access them i get a nested transactions not supported because i wasnt closing the session.

When i close the session like session.close() i get a session was already closed error. When i use the HibernateUtil.close() (because i read i should to close the threadLocale) i get LazyInitializationException: could not initialize proxy - no Session.

Would i need to save/persist the list after the first db hit? Or change from lazy to eager loading? Even after reading about them, I don't fully understand how they apply to this instance, and don't know exactly how to specify eager loading if i do need to. I have seen this annotation useage fetch = FetchType.LAZY but how do i use the mapping tags to specify eager?

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;
        }

Flights Mapping

<?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>

Upvotes: 0

Views: 3454

Answers (1)

Zeus
Zeus

Reputation: 6566

session.getCurrentSession() automatically closes transaction/session for you. If you look at this API, they say that if you call session.openSession(); you have to close the session manually in the finally block.

For the problem you are having with lazy properties, you have to fetch the lazy properties when in session, ie., when the transaction is open/ just before closing the session. In your case before the commit() is called. If you call the lazy properties after that code has been executed, you will get that error.

To avoid this problem, I usually write a several of services(for same parent object) to load different lazy items of the parent object and close the session. Or you can set the fetch type to eager.

Upvotes: 1

Related Questions