Hibernate 为子类 dao 使用事务管理器

Hibernate use transaction manager for subclass dao

我正在制作一个 spring 带休眠功能的启动应用程序,并且我有一个 DAO 层次结构。 我还有 2 个事务管理器用于两个不同的数据库。

我有一个 BaseDao、一个 BaseDB1Dao 和一个 BaseDB2Dao。

Base dao如下。我没有保留 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 注释。我只 post 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();
    }
}

当我运行上面的代码时,读取查询工作正常并从各自的数据库中提取。但是 像创建这样的事务性查询不起作用并且失败并出现错误

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的子dao之一UserDao只是调用了BaseDao中定义的基本create函数。

一个解决方案是我将 @Transactional 添加到 BaseDaoImpl,如下所示

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

    protected abstract Session getSession();
....

然而,这会导致 另一个 错误 both 读取和写入。发生这种情况是因为用户创建函数是从 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

所以总的问题是:有没有办法使用子class的tranactionManager作为父class[=中的一个函数15=]

您需要提供一个名为 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);
}