2016-03-11 76 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