Я создаю приложение для загрузки весны с спящим режимом, и у меня есть иерархия DAO. У меня также есть 2 менеджера транзакций для двух разных баз данных.Hibernate использовать диспетчер транзакций для подкласса dao
У меня есть BaseDao, BaseDB1Dao и BaseDB2Dao.
База dao выглядит следующим образом. Я не поддерживаю @Transactional аннотацию с 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);
}
}
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 класса за ребенком функция в родительском классе
Спасибо. Способ, которым мой проект настроен, состоит в том, что у меня есть два отдельных файла конфигурации, имеющие структуру, как показано http://stackoverflow.com/questions/35925768/hibernate-multiple-database-configuration-files. Как бы я назвал эту функцию, поэтому она берет обоих менеджеров транзакций? – Sakib
HibernateTransactionManager - это PlatformTransactionManager, поэтому вы определяете один из них для каждого источника данных и передаете его этому методу. Просто убедитесь, что имя метода у двух других менеджеров транзакций имеет другое имя. (имя метода - имя компонента) –
Спасибо, что сработали. Я просто добавил это в свой основной файл конфигурации базы данных и объединил оба моих файла конфигурации базы данных. – Sakib