Как использовать транзакционную аннотацию, когда конфиг транзакцииManager условно весной? - PullRequest
2 голосов
/ 12 июня 2019

Я использую несколько источников данных в своем весеннем проекте. Я включаю / отключаю их путем ручной настройки во время запуска проекта. Все они могут быть активными одновременно. Таким образом, компонентactionManager может быть активным или нет.

Я реализую это с помощью аннотации @Conditional в классе конфигурации Spring. Когда я использую отключенную транзакционную аннотацию в методах, у меня возникает NoSuchBeanDefinitionException.

Когда я определяю bean-компонентactionManager условно, как использовать аннотацию транзакций для методов?

Bean-компонент archiveTransactionManager не создается с помощью аннотации @Conditional, и я хочу, чтобы весенняя проверка пропускалась для проверки bean-компонента в диспетчере условных транзакций.

Для условных bean-компонентов sessionFactory я установил параметр 'required' в аннотации Autowired на false, чтобы пружина не выдавала исключение NoSuchBeanDefinitionException, но что мне делать для @Transactional?

Класс конфигурации

    @Bean("archiveTransactionManager")
    @Conditional(ArchiveCondition.class)
    public HibernateTransactionManager archiveTransactionManager() {
        HibernateTransactionManager transactionManager = new HibernateTransactionManager();
        transactionManager.setSessionFactory(archiveSessionFactory());
        return transactionManager;
    }

Транзакционный метод

    @Transactional(value = "archiveTransactionManager", readOnly = true)
    private List<DocumentItem> loadArchivedDocumentItem() {...}

Использование

if(GeneralSetting.isArchive)
   documentService.loadArchivedDocumentItem();

Текущий результат:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'archiveTransactionManager' available: No matching PlatformTransactionManager bean found for qualifier 'archiveTransactionManager' - neither qualifier match nor bean name match!

Я хочу валидный бин весеннего пропуска условных бинов транзакции в некоторых ситуациях, которые не создаются условиями .

Ответы [ 3 ]

2 голосов
/ 18 июня 2019

Я реализую неоперативный SessionFactory и создаю его экземпляр в классе конфигурации Spring при каждом отключении archive_mode:

SpringConfig.java

    @Bean("archiveSessionFactory")
    public SessionFactory archiveSessionFactory() {
        return ServerConf.ARCHIVE_MODE ? createNormalSessionFactory() : new DummySessionFactory();
    }

    @Bean("archiveTransactionManager")
    public HibernateTransactionManager archiveTransactionManager() {
        HibernateTransactionManager transactionManager = new HibernateTransactionManager();
        transactionManager.setSessionFactory(archiveSessionFactory());
        return transactionManager;
    }

DummySessionFactory.java

public class DummySessionFactory implements SessionFactory {
...
    // These two methods call in spring initializing and we have to implement them
    @Override
    public Metamodel getMetamodel() {
       return new MetamodelImpl(null);
    }

    @Override
    public Map<String, Object> getProperties() {
       return null;
    }

    //Throw suitable exception in other methods
    @Override
    public Session getCurrentSession() throws HibernateException {
        throw new HibernateException("Desired mode is Disabled");
    }
...
}
0 голосов
/ 12 июня 2019

Я бы воспринял это как запасной сценарий, когда вы должны восстановиться после сбоя.В этом случае укажите метод вызова метода, аннотированный

@Transactional(value = "archiveTransactionManager", readOnly = true)

, в случае сбоя (или исключения), вызов метода, аннотированный

@Transactional(value = "alternativeTransactionManager", readOnly = true)

public void doSomething() {
    try {
        tryFirst();
    } catch (Exception e) {
        tryAlternative();
    }
}

@Transactional(value = "archiveTransactionManager", readOnly = true)
public void tryFirst() {

}

@Transactional(value = "alternativeTransactionManager", readOnly = true)
public void tryAlternative() {

}

Имейте в виду, вы должны объявить их обоих.

0 голосов
/ 12 июня 2019

Вы использовали неправильную аннотацию, чтобы назвать бин.@Qualifier используется в точке ввода для указания имени.Вам нужно дать бобу имя с @Bean.Итак, ваше определение бина должно выглядеть так:

@Bean("archiveTransactionManager")
@Conditional(ArchiveCondition.class)
public HibernateTransactionManager archiveTransactionManager() {
  HibernateTransactionManager transactionManager = new HibernateTransactionManager();
  transactionManager.setSessionFactory(archiveSessionFactory());
  return transactionManager;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...