I am making a spring boot app with hibernate and I have a hierarchy of DAOs. I also have 2 transaction managers for two different databases.
I have a BaseDao, a BaseDB1Dao, and BaseDB2Dao.
The Base dao is as follows. I do not keep the @Transactional annotation with the BaseDao.
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);
}
}
The BaseDB1Dao and BaseDB2Dao's inherit and extend BaseDao with additional functions related to the schemas in addition to the basic functions. The main difference is that I specify the @transactional annotation as follows. I only post BaseDB1 because they are both almost identical
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();
}
}
When I run the above code, the read queries work fine and pull from respective DBs. But transctional queries like create do not work and fail with error
Could not obtain transaction-synchronized Session for current thread; nested exception is org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
This is because the One of the sub dao of BaseDB1Da0, UserDao, just calls the basic create function defined in BaseDao.
One solution is I add @Transactional to BaseDaoImpl as follows
@Transactional
@Repository
public abstract class BaseDaoImpl<T extends Serializable> implements BaseDao<T>{
protected abstract Session getSession();
....
However that results in another error for both reads and writes. This happens because the user create function is inherited from the BaseDao and it goes there when the create function is called
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
So the overall question is: Is there a way to use the tranactionManager of the child class for a function in the parent class