我有以前struts+hibernate的一些代碼。現(xiàn)在想加入spring,但是既然spring是為了分離程序間的耦合,當(dāng)然,也不能和spring結(jié)合的太緊蜜。
所以,我盡量不在manager和DAO里使用spring的類。于是寫了下面的幾個(gè)基礎(chǔ)類,希望以后即使修改也不用改動(dòng)太大。
public interface BaseDAO {
public Long add(Object object) throws HibernateException;
}
public class BaseDAOImpl extends HibernateDaoSupport {
//這里是希望spring在構(gòu)造這個(gè)類時(shí)將sessionFactory傳遞給HibernateDaoSupport.setSessionFactory(),并初始化一個(gè)session對(duì)象
protected Session session =null;
public BaseDAOImpl(SessionFactory sessionFactory) {
this.setSessionFactory(sessionFactory);
this.session = this.getSession();
}
public Long add(Object object) throws HibernateException{
Long reval=null;
reval=(Long)session.save(object);
return reval;
}
public interface BaseManager {
public Long add(Object object) throws BusinessLogicException, HibernateException;
}
public class BaseManagerImpl {
}
具體的UserDAO和UserManager如下:
public interface UserDAO extends BaseDAO{
}
public interface UserManager extends BaseManager{
}
public class UserDAOImpl extends BaseDAOImpl implements UserDAO{
}
public class UserManagerImpl extends BaseManagerImpl implements UserManager{
public Long add(Object object) throws BusinessLogicException, HibernateException {
return userDAO.add(object);
}
}
spring配置文件如下:
<beans>
<description>bean test</description>
<bean id="hibernateSessionFactory" factory-method="getSessionFactory"
class="huye.common.util.HibernateUtil" />
<bean id="hibernateTransactionManager"
class="org.springframework.orm.hibernate.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="hibernateSessionFactory" />
</property>
</bean>
<bean id="UserDAO" class="huye.user.proxy.impl.UserDAOImpl">
<constructor-arg><ref local="hibernateSessionFactory"/></constructor-arg>
</bean>
<bean id="UserManagerTarget" class="huye.user.proxy.impl.UserManagerImpl">
</bean>
<bean id="UserManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="hibernateTransactionManager" />
</property>
<property name="target">
<ref local="UserManagerTarget" />
</property>
<property name="proxyTargetClass">
<value>false</value>
</property>
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED,-java.lang.Exception</prop>
<prop key="update*">PROPAGATION_REQUIRED,-java.lang.Exception</prop>
<prop key="delete*">PROPAGATION_REQUIRED,-java.lang.Exception</prop>
<prop key="get*">PROPAGATION_REQUIRED,-java.lang.Exception</prop>
</props>
</property>
</bean>
</beans>
然望能通過(guò)這樣的結(jié)構(gòu)達(dá)到即使以后去掉了spring,我只需要修改baseDAOImpl和BaseManagerImpl類就可以了。
可是運(yùn)行后發(fā)現(xiàn)事務(wù)沒有提交,但也不出現(xiàn)錯(cuò)誤提示。
連續(xù)試驗(yàn)了一天,并使用sqlserver事件查看器,才發(fā)現(xiàn)問(wèn)題。原來(lái),add時(shí)同時(shí)建立了兩個(gè)連接,連接1沒有執(zhí)行SQL語(yǔ)句,但提交了事務(wù),連接2只執(zhí)行了SQL語(yǔ)句。
可能是因?yàn)槲野裺essionFactory放在了DAO的構(gòu)造方法里,而不是setter里。
把BaseDAOImpl改造一下,構(gòu)造方法去掉,加入
public void setSessionFactory2(SessionFactory sessionFactory){
this.setSessionFactory(sessionFactory);
this.session = this.getSession();
System.out.println("session=" + session);
}
并在spring配置文件里做相應(yīng)配置。
這次發(fā)現(xiàn)雖然和數(shù)據(jù)庫(kù)只建立了一個(gè)連接,但是卻沒有執(zhí)行SQL語(yǔ)句。
奇怪了。
把a(bǔ)dd方法改一下:
public Long add(Object object) throws HibernateException{
Long reval=null;
reval=(Long)getSession().save(object);
return reval;
}
這次才成功,數(shù)據(jù)正確保存。
但是這樣的話,我所有的DAO都要把session.method改成getSession().method。
這也太麻煩了。
只是很奇怪,明明只有一個(gè)session,不知道為什么不執(zhí)行呢?
等下次解決吧。