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);
}
我正在制作一个 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);
}