2014-02-19 68 views
0

我有dao擴展通用dao來執行基本操作,如保存,獲取,刪除和更新數據庫中的Object。在DAO中自動創建事務 - spring mvc和hibernate

在每一個行動我必須手動啓動和提交交易。我試圖找到辦法自動做到這一點。

這是實現通用的DAO:

@Transactional 
public abstract class GenericDaoImpl<T> implements IGenericDao<T> { 
    @Autowired 
    protected SessionFactory sessionFactory; 

protected Session getCurrentSession(){ 
    return sessionFactory.getCurrentSession(); 
} 

private Class<T> type; 

public GenericDaoImpl() { 
    Type t = getClass().getGenericSuperclass(); 
    ParameterizedType pt = (ParameterizedType) t; 
    type = (Class) pt.getActualTypeArguments()[0]; 
} 

@Override 
@Transactional 
public void save(final T t) { 
    Session session = getCurrentSession(); 
    Transaction tr = session.beginTransaction(); 
    session.save(t); 
    tr.commit(); 
} 
} 

當我刪除此兩行:

Transaction tr = session.beginTransaction(); 
tr.commit(); 

它不會工作。我認爲@Transactional註釋爲我處理交易。

這是我的豆配置:

<bean id="sessionFactory" 
      class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
     <property name="dataSource" ref="dataSource"></property> 
     <property name="configLocation"> 
      <value>WEB-INF/hibernate.cfg.xml</value> 
     </property> 
    </bean> 



    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
     <property name="dataSource" ref="dataSource" /> 
     <property name="sessionFactory" ref="sessionFactory" /> 
    </bean> 

    <tx:annotation-driven transaction-manager="transactionManager"/> 

    <!-- this is the dao object that we want to make transactional --> 
    <bean id="testDao" class="com.springapp.mvc.dao.GenericDaoImpl" abstract="true"/> 



    <!-- the transactional advice --> 
    <tx:advice id="txAdvice" transaction-manager="transactionManager"> 
     <tx:attributes> 
      <!-- all methods starting with 'get' are read-only --> 
      <tx:method name="get*" read-only="true" /> 
      <!-- other methods use the default transaction settings (see below) --> 
      <tx:method name="*" propagation="REQUIRED" /> 
     </tx:attributes> 
    </tx:advice> 

我應該怎麼做,以限制對Spring事務管理?

+0

哪種方法調用您的保存方法?這可能是代理問題。僅當您通過代理調用您的方法時,註釋纔會起作用。 –

+0

@ArnaudPotier我有服務,在服務具體道,我稱之爲方法。那個具體的dao擴展了我的GenericDao。 我第一次聽到代理,所以有可能我沒有使用它。你能告訴我更多關於它嗎? –

+0

我添加了一個普遍的答案。 –

回答

0

它確實只要你有正確的配置,

如果使用代理訪問你的bean的方法,因爲這種方法:

public class MyServiceImpl implements MyService 

    @Autowired 
    private GenericDao dao; 

    public void someMethod() { 
     dao.save(myObject) 
    } 

    //bla bla 
} 

只要你在你的XML配置有<context:annotation-config/>,它應自動裝載您的Dao並調用保存方法。

但它不會被封裝在事務中:爲了通過註釋來處理事務,Spring使用包裝方法調用的代理。您可以在調試模塊的IDE中看到這些調用。 帶有「$ proxy ...」的巨大堆棧調用由spring及其proxys創建。

<tx:annotation-driven>指定spring應該使用註釋來管理事務。 但是,它需要一個代理來圍繞方法調用進行打包。 因此,您需要將以下行添加到您的XML:<aop:aspectj-autoproxy />

希望這有助於。

+0

我將添加到我的xml中,但仍然不會自動處理事務。 –