I use multiple datasources in my spring project. I enable/disable them by manual config in project startup time. At a time all of them may be active So a transactionManager bean maybe active or not.
I implement it by @Conditional annotation in spring configuration class. When I use a disable transactional annotation on methods I have NoSuchBeanDefinitionException.
When I define transactionManager bean conditionally how to use the transactional annotioan on methods?
The archiveTransactionManager bean doesn't create by @Conditional annotation and I want spring skip checking for bean validation of conditional transaction manager.
For conditional sessionFactory beans I set 'required' parameter in Autowired annotation to false for prevent spring to throw NoSuchBeanDefinitionException but what do I do for @Transactional ?
Configuration class
@Bean("archiveTransactionManager")
@Conditional(ArchiveCondition.class)
public HibernateTransactionManager archiveTransactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(archiveSessionFactory());
return transactionManager;
}
Transactional method
@Transactional(value = "archiveTransactionManager", readOnly = true)
private List<DocumentItem> loadArchivedDocumentItem() {...}
Usage
if(GeneralSetting.isArchive)
documentService.loadArchivedDocumentItem();
Current result:
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!
I want spring skip bean validation of conditional transactionManager beans on some situations that they don't create by conditions.
I implement a no-op SessionFactory and instantiate it in spring configuration class whenever archive_mode is disable :
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");
}
...
}