spring整合struts框架遇到的一个诡异的问题
从spring中获取sessionFactory,用来初始化一个hibernateTempleate。调用如下代码,发现session是自动关闭的。
Session s = (Session) h.execute(new HibernateCallback() {
public Object doInHibernate(Session arg0) throws HibernateException,
SQLException {
System.out.println(arg0);
return arg0;
}
});
System.out.println(s);
输出结果:
SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] ollectionCreations=[] collectionRemovals=[] collectionUpdates=[]])
SessionImpl(<closed>)
在DAO中,同样初始化了一个hibernateTemplate。代码如下:(是用spring配置注入的)
public void setSessionFactory(SessionFactory sessionFactory) {
hibernateTemplate = new HibernateTemplate(sessionFactory);
}
我在他这里加入了一段测试代码:
public void setSessionFactory(SessionFactory sessionFactory) {
hibernateTemplate = new HibernateTemplate(sessionFactory);
Session s = (Session) hibernateTemplate.execute(new HibernateCallback() {
public Object doInHibernate(Session arg0) throws HibernateException,
SQLException {
System.out.println(arg0);
return arg0;
}
});
}
输出结果正常。同上。
但是问题出现了,我在dao的方法中同样加入了这段代码。如下:
public Account findById(Integer id) throws DAOException {
Session s = (Session) hibernateTemplate.execute(new HibernateCallback() {
public Object doInHibernate(Session arg0) throws HibernateException,
SQLException {
System.out.println(arg0);
return arg0;
}
});
System.out.println(s);
return (Account) hibernateTemplate.get(Account.class, id);
}
这段代码会在一个Action中被调用,调用之后的输出缺不同了,session并没有关闭,即使手动写入代码,s.close();session依然不会关闭,dao加载的时候,跟调用find方法的时候用的是同一个hibernateTemplate,但是为什么测试方法执行的结果截然不同呢?费解……求大神指点……
PS:有别人写的代码就一切正常,为了检验我把他的工程拿过来我这里执行,还是一切正常,我的还是不行。然后我换他的jar包他换我的jar包 ,问题依旧。最后我把tomcat清空了,重新实验,依旧。真的无奈了……
我交换了我俩的dao文件,问题依旧。我交换了sessionFactory的bean的配置,问题依旧……
我也观察了我俩的实体类映射文件,设置几乎一样。我俩Action有差别,account这个类做修改操作的时候由于页面上传回来的数据不足,(account有20个属性,页面上只有10来个)我用了隐藏域,根据ID查找出新对象,传到隐藏域里,提交表单的时候属性再传回来。而他是根据ID查找出一个新的account对象,把页面上没有的属性直接set进从页面传回的对象中去。问题出在这,我会报一个异常,说session中有同一个ID两个account对象,而他不报,我就发现他第一次根据ID查询对象的时候session用完了就关闭了。update的时候新拿一个session。我的没有关闭……所以有异常。不解啊……
大神 help~
配置文件的部分代码
<!-- DBCP连接池 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="url" value="jdbc:oracle:thin:@192.168.1.150:1521:tarena"></property>
<property name="driverClassName" value="oracle.jdbc.OracleDriver"></property>
<property name="username" value="jsd"></property>
<property name="password" value="jsd"></property>
<property name="initialSize" value="2"></property>
<property name="maxActive" value="10"></property>
<property name="maxWait" value="5000"></property>
</bean>
<!-- sessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>com/netctoss/entity/Cost.hbm.xml</value>
<value>com/netctoss/entity/Account.hbm.xml</value>
<value>com/netctoss/entity/Service.hbm.xml</value>
</list>
</property>
</bean>
<!-- 配置声明式事务 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="find*" read-only="true" propagation="NOT_SUPPORTED"
isolation="READ_COMMITTED" />
<tx:method name="*" propagation="REQUIRED" isolation="READ_COMMITTED" />
</tx:attributes>
</tx:advice>
<!-- 配置AOP -->
<aop:config>
<aop:pointcut expression="execution(* com.netctoss.action..*.*(..))"
id="cure" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="cure" />
</aop:config>
<!-- 配置dao -->
<bean id="costDao" class="com.netctoss.dao.cost.impl.CostDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 配置action -->
<bean id="updateCost" class="com.netctoss.action.cost.UpdateCostAction"
scope="prototype">
<property name="costDao" ref="costDao"></property>
</bean>
Dao部分代码:
private HibernateTemplate hibernateTemplate;
public void setSessionFactory(SessionFactory sessionFactory) {
Session s = (Session) hibernateTemplate.execute(new HibernateCallback() {
public Object doInHibernate(Session arg0) throws HibernateException,
SQLException {
System.out.println(arg0);
return arg0;
}
});
System.out.println(s);
hibernateTemplate = new HibernateTemplate(sessionFactory);
}
public Account findById(Integer id) throws DAOException {
Session s = (Session) hibernateTemplate.execute(new HibernateCallback() {
public Object doInHibernate(Session arg0) throws HibernateException,
SQLException {
System.out.println(arg0);
return arg0;
}
});
System.out.println(s);
return (Account) hibernateTemplate.get(Account.class, id);
}
映射文件:
<class name="Account" table="ACCOUNT_XUE">
<id name="id" column="ID">
<generator class="native">
<param name="sequence">seq_account_xue</param>
</generator>
</id>
<property name="birthdate" column="BIRTHDATE" type="date"></property>
<property name="closeDate" column="CLOSE_DATE" type="date"></property>
<property name="createDate" column="CREATE_DATE" type="date"></property>
<property name="email" column="EMAIL"></property>
<property name="gender" column="GENDER"></property>
<property name="idcardNo" column="IDCARD_NO"></property>
<property name="lastLoginIp" column="LAST_LOGIN_IP"></property>
<property name="lastLoginTime" column="LAST_LOGIN_TIME" type="date"></property>
<property name="loginName" column="LOGIN_NAME"></property>
<property name="loginPasswd" column="LOGIN_PASSWD"></property>
<property name="mailAddress" column="MAILADDRESS"></property>
<property name="occupation" column="OCCUPATION"></property>
<property name="pauseDate" column="PAUSE_DATE" type="date"></property>
<property name="qq" column="QQ"></property>
<property name="realName" column="REAL_NAME"></property>
<property name="recommenderId" column="RECOMMENDER_ID"></property>
<property name="status" column="STATUS"></property>
<property name="telephone" column="TELEPHONE"></property>
<property name="zipCode" column="ZIPCODE"></property>
<set name="services" cascade="all" lazy="false">
<key column="ACCOUNT_ID"></key>
<one-to-many class="Service" />
</set>
</class>
Action部分代码
private Account account;
private IAccountDAO accDao;
public String updateAccount() {
try {
Account a=accDao.findById(account.getId());
account.setServices(a.getServices());
accDao.updateAccount(account);
} catch (DAOException e) {
e.printStackTrace();
return "error";
}
return "success";
}