我有以前struts+hibernate的一些代碼?,F在想加入spring,但是既然spring是為了分離程序間的耦合,當然,也不能和spring結合的太緊蜜。
所以,我盡量不在manager和DAO里使用spring的類(lèi)。于是寫(xiě)了下面的幾個(gè)基礎類(lèi),希望以后即使修改也不用改動(dòng)太大。
public interface BaseDAO {
public Long add(Object object) throws HibernateException;
}
public class BaseDAOImpl extends HibernateDaoSupport {
//這里是希望spring在構造這個(gè)類(lèi)時(shí)將sessionFactory傳遞給HibernateDaoSupport.setSessionFactory(),并初始化一個(gè)session對象
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ò)這樣的結構達到即使以后去掉了spring,我只需要修改baseDAOImpl和BaseManagerImpl類(lèi)就可以了。
可是運行后發(fā)現事務(wù)沒(méi)有提交,但也不出現錯誤提示。
連續試驗了一天,并使用sqlserver事件查看器,才發(fā)現問(wèn)題。原來(lái),add時(shí)同時(shí)建立了兩個(gè)連接,連接1沒(méi)有執行SQL語(yǔ)句,但提交了事務(wù),連接2只執行了SQL語(yǔ)句。
可能是因為我把sessionFactory放在了DAO的構造方法里,而不是setter里。
把BaseDAOImpl改造一下,構造方法去掉,加入
public void setSessionFactory2(SessionFactory sessionFactory){
this.setSessionFactory(sessionFactory);
this.session = this.getSession();
System.out.println("session=" + session);
}
并在spring配置文件里做相應配置。
這次發(fā)現雖然和數據庫只建立了一個(gè)連接,但是卻沒(méi)有執行SQL語(yǔ)句。
奇怪了。
把add方法改一下:
public Long add(Object object) throws HibernateException{
Long reval=null;
reval=(Long)getSession().save(object);
return reval;
}
這次才成功,數據正確保存。
但是這樣的話(huà),我所有的DAO都要把session.method改成getSession().method。
這也太麻煩了。
只是很奇怪,明明只有一個(gè)session,不知道為什么不執行呢?
等下次解決吧。