2016-03-11 33 views
1

我正在做一個春季啓動應用與休眠,我有一個層次結構的DAO。 我也有兩個不同的數據庫的事務管理器。休眠使用事務管理器的子類dao

我有一個BaseDao,一個BaseDB1Dao和BaseDB2Dao。

基地道如下。我不保留BaseDao的@Transactional註釋。

public interface BaseDao<T extends Serializable> { 

    T create(T t); 

    T read(Class<T> entityClass, long id); 

    void update(T t); 

} 

public abstract class BaseDaoImpl<T extends Serializable> implements BaseDao<T>{ 

    protected abstract Session getSession(); 

    @Override 
    public T create(T t) { 
     getSession().save(t); 
     return null; 
    } 

    @Override 
    @SuppressWarnings("unchecked") 
    public T read(Class<T> entityClass, long id) { 
     return (T) getSession().get(entityClass, id); 
    } 

    @Override 
    public void update(T t) { 
     getSession().update(t); 
    } 
} 

的BaseDB1Dao和BaseDB2Dao的繼承與除基本功能相關的架構附加功能擴展BaseDao。主要區別在於我指定@transactional註釋如下。我只發佈BaseDB1因爲他們都幾乎相同

public interface BaseDB1Dao<T extends Serializable> extends BaseDao<T>{ 
    // add additional generic transaction functions here 
} 

@Repository("baseDB1Dao") 
@Transactional("db1TransactionManager") 
public class BaseDB1DaoImpl<T extends Serializable> extends BaseDaoImpl<T> implements BaseDB1Dao<T> { 

    @Autowired 
    @Qualifier("db1SessionFactory") 
    private SessionFactory sessionFactory; 

    @Override 
    protected Session getSession() { 
     return sessionFactory.getCurrentSession(); 
    } 
} 

當我運行上面的代碼中,讀取查詢做工精細,並從各自的數據塊拉。但是像transctional查詢創建不工作,失敗,錯誤

Could not obtain transaction-synchronized Session for current thread; nested exception is org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread 

這是因爲一個BaseDB1Da0,userDAO的的子道,只需調用BaseDao定義的基本功能創建。

一種解決方案是我加@Transactional到BaseDaoImpl如下

@Transactional 
@Repository 
public abstract class BaseDaoImpl<T extends Serializable> implements BaseDao<T>{ 

    protected abstract Session getSession(); 
.... 

然而,在導致另一個誤差讀取和寫入。這是因爲用戶創建功能從BaseDao繼承,並去那裏當創建函數被調用

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.transaction.PlatformTransactionManager] is defined: expected single matching bean but found 2: db1TransactionManager,db2TransactionManager 

所以整體的問題是:是否有使用tranactionManager子類的一種方式父類中的函數

回答

1

您需要提供名爲transactionManager的專用bean,以處理其他事務管理器(db1TransactionManager,db2TransactionManager)。 Spring簡單地通過定義名爲tpye ChainedTransactionManager的transactionManager的自定義bean來支持這一點。詳細聲明取決於您的設置,因此不保證以下工作。

@Autowired 
@Bean(name = "transactionManager") 
public PlatformTransactionManager transactionManager(PlatformTransactionManager db1TransactionManager, PlatformTransactionManager db2TransactionManager) 
     throws Exception { 
    return new ChainedTransactionManager(db1TransactionManager, 
      db2TransactionManager); 
} 
+0

謝謝。我的項目設置的方式是,我有兩個單獨的配置文件,其結構如http://stackoverflow.com/questions/35925768/hibernate-multiple-database-configuration-files所示。 我該如何調用這個函數,因此它需要兩個事務管理器? – Sakib

+0

HibernateTransactionManager是一個PlatformTransactionManager,因此您可以爲每個數據源定義其中的一個,並將其傳遞給此方法。只要確保兩個其他事務管理器的方法名稱具有不同的名稱即可。 (方法名稱是豆的名字) –

+0

謝謝你的工作。我只是將其添加到我的主數據庫配置文件併合並了我的數據庫配置文件。 – Sakib