我有两个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
,但我如何使用映射标签来指定eager?
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>
答案 0 :(得分:1)
session.getCurrentSession()
会自动关闭您的交易/会话。如果您查看this API,他们会说如果您致电session.openSession()
;你必须在finally块中手动关闭会话。
对于您使用延迟属性的问题,您必须在会话期间(即,当事务处于打开状态时/在关闭会话之前)获取延迟属性。在你的情况下调用commit()之前。如果在执行该代码后调用惰性属性,则会出现该错误。
为了避免这个问题,我经常编写几个服务(对于同一个父对象)来加载父对象的不同惰性项并关闭会话。或者您可以将抓取类型设置为eager
。