Spring + Hibernate : Multitenancy with MySQL Read Replica support - java

I am moving an existing Spring boot application from Multitenancy to Database per tenant model. Some common Entities are in the Master database, whereas others will be in their respective database. These classes have been implemented and worked fine. Source to get ma started is this: https://callistaenterprise.se/blogg/teknik/2020/10/03/multi-tenancy-with-spring-boot-part3/
Classes
MasterPersistenceConfig.java (MasterDatabaseRepository below are the JPA repositories that are gonna be in the master database)
TenantPersistenceConfig.java
DynamicDataSourceBasedMultiTenantConnectionProvider.java
CurrentTenantIdentifierResolverImpl.java
application.yml
MasterPersistenceConfig.java (MasterDatabaseRepository below are the JPA repositories that are gonna be in the master database)
#Log4j2
#Configuration
#EnableJpaRepositories(
basePackages = { "${multitenancy.base-package}" },
entityManagerFactoryRef = "masterEntityManagerFactory",
transactionManagerRef = "masterTransactionManager",
includeFilters = {
#ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = MasterDatabaseRepository.class)
}
)
#EnableConfigurationProperties({DataSourceProperties.class, JpaProperties.class})
public class MasterPersistenceConfig {
private final ConfigurableListableBeanFactory beanFactory;
private final JpaProperties jpaProperties;
private final String entityPackages;
#Autowired
public MasterPersistenceConfig(ConfigurableListableBeanFactory beanFactory,
JpaProperties jpaProperties,
#Value("${multitenancy.master.entityManager.packages}")
String entityPackages) {
this.beanFactory = beanFactory;
this.jpaProperties = jpaProperties;
this.entityPackages = entityPackages;
}
#Bean
public LocalContainerEntityManagerFactoryBean masterEntityManagerFactory(
#Qualifier("masterDataSource") DataSource dataSource) {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setPersistenceUnitName("master-persistence-unit");
em.setPackagesToScan(entityPackages);
em.setDataSource(dataSource);
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
Map<String, Object> properties = new HashMap<>(this.jpaProperties.getProperties());
properties.put(AvailableSettings.PHYSICAL_NAMING_STRATEGY, "org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy");
properties.put(AvailableSettings.IMPLICIT_NAMING_STRATEGY, "org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy");
properties.put(AvailableSettings.BEAN_CONTAINER, new SpringBeanContainer(this.beanFactory));
em.setJpaPropertyMap(properties);
return em;
}
#Bean
public JpaTransactionManager masterTransactionManager(
#Qualifier("masterEntityManagerFactory") EntityManagerFactory emf) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
}
TenantPersistenceConfig.java (Using bean of DynamicDataSourceBasedMultiTenantConnectionProvider and CurrentTenantIdentifierResolverImpl to create entityManagerFactory)
#Log4j2
#Configuration
#EnableJpaRepositories(
basePackages = {"${multitenancy.base-package}"},
entityManagerFactoryRef = "tenantEntityManagerFactory",
transactionManagerRef = "tenantTransactionManager",
includeFilters = #Filter(type = FilterType.ASSIGNABLE_TYPE, value = JpaRepository.class),
excludeFilters = #Filter(type = FilterType.ASSIGNABLE_TYPE, classes = MasterDatabaseRepository.class)
)
#EnableConfigurationProperties(JpaProperties.class)
public class TenantPersistenceConfig {
private final ConfigurableListableBeanFactory beanFactory;
private final JpaProperties jpaProperties;
private final String entityPackages;
#Autowired
public TenantPersistenceConfig(
ConfigurableListableBeanFactory beanFactory,
JpaProperties jpaProperties,
#Value("${multitenancy.tenant.entityManager.packages}")
String entityPackages) {
this.beanFactory = beanFactory;
this.jpaProperties = jpaProperties;
this.entityPackages = entityPackages;
}
#Primary
#Bean
public LocalContainerEntityManagerFactoryBean tenantEntityManagerFactory(
#Qualifier("dynamicDataSourceBasedMultiTenantConnectionProvider") MultiTenantConnectionProvider connectionProvider,
#Qualifier("currentTenantIdentifierResolver") CurrentTenantIdentifierResolver tenantResolver) {
LocalContainerEntityManagerFactoryBean emfBean = new LocalContainerEntityManagerFactoryBean();
emfBean.setPersistenceUnitName("tenant-persistence-unit");
emfBean.setPackagesToScan(entityPackages);
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
emfBean.setJpaVendorAdapter(vendorAdapter);
Map<String, Object> properties = new HashMap<>(this.jpaProperties.getProperties());
properties.put(AvailableSettings.PHYSICAL_NAMING_STRATEGY, "org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy");
properties.put(AvailableSettings.IMPLICIT_NAMING_STRATEGY, "org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy");
properties.put(AvailableSettings.BEAN_CONTAINER, new SpringBeanContainer(this.beanFactory));
properties.put(AvailableSettings.MULTI_TENANT, MultiTenancyStrategy.DATABASE);
properties.put(AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER, connectionProvider);
properties.put(AvailableSettings.MULTI_TENANT_IDENTIFIER_RESOLVER, tenantResolver);
emfBean.setJpaPropertyMap(properties);
return emfBean;
}
#Primary
#Bean
public JpaTransactionManager tenantTransactionManager(
#Qualifier("tenantEntityManagerFactory") EntityManagerFactory emf) {
JpaTransactionManager tenantTransactionManager = new JpaTransactionManager();
tenantTransactionManager.setEntityManagerFactory(emf);
return tenantTransactionManager;
}
#Bean
public TenantDataSource tenantDataSource(#Qualifier("dynamicDataSourceBasedMultiTenantConnectionProvider") MultiTenantConnectionProvider connectionProvider,
#Qualifier("currentTenantIdentifierResolver") CurrentTenantIdentifierResolver tenantResolver) {
return new TenantDataSource(connectionProvider, tenantResolver);
}
#Bean
public NamedParameterJdbcTemplate namedParameterJdbcTemplateRead(#Qualifier("tenantDataSource") TenantDataSource tenantDataSource) {
return new NamedParameterJdbcTemplate(tenantDataSource);
}
#Bean
#Primary
public JdbcTemplate tenantJdbcTemplate(#Qualifier("tenantDataSource") TenantDataSource tenantDataSource) {
return new JdbcTemplate(tenantDataSource);
}
}
DynamicDataSourceBasedMultiTenantConnectionProvider (Uses TenantRepository, which MasterEntityManager manages)
#Log4j2
#Component
public class DynamicDataSourceBasedMultiTenantConnectionProvider
extends AbstractDataSourceBasedMultiTenantConnectionProviderImpl {
private static final String TENANT_POOL_NAME_SUFFIX = "DataSource";
#Autowired
#Qualifier("masterDataSource")
private DataSource masterDataSource;
#Qualifier("masterDataSourceProperties")
#Autowired
private DataSourceProperties dataSourceProperties;
#Autowired
private TenantRepository masterTenantRepository;
private Map<String, HikariDataSource> tenantDataSources = new HashMap<>();
#Autowired
private DbProperties properties;
public DynamicDataSourceBasedMultiTenantConnectionProvider() {
}
public HikariDataSource getDataSource(String code) {
// masterTenantRepository usages
}
#PostConstruct
public Map<String, DataSource> getAll() {
// masterTenantRepository usages
}
#Override
protected HikariDataSource selectAnyDataSource() {
return (HikariDataSource) masterDataSource;
}
#Override
protected HikariDataSource selectDataSource(String tenantIdentifier) {
return getDataSource(tenantIdentifier);
}
private HikariDataSource createAndConfigureDataSource(Tenant tenant) {
// Datasource build and return
}
#Override
public Connection getAnyConnection() throws SQLException {
// get connection using datasource
}
#Override
public Connection getConnection(String tenantIdentifier) throws SQLException {
// get connection using datasource
}
}
CurrentTenantIdentifierResolverImpl (Uses TenantRepository, which MasterEntityManager manages)
#Log4j2
#Component("currentTenantIdentifierResolver")
public class CurrentTenantIdentifierResolverImpl implements CurrentTenantIdentifierResolver {
#Autowired
private TenantRepository tenantRepository;
#Override
public String resolveCurrentTenantIdentifier() {
// tenantRepository usages
}
#Override
public boolean validateExistingCurrentSessions() {
return true;
}
}
application.yml
multitenancy:
base-package: packageX
datasource-cache:
maximumSize: 100
expireAfterAccess: 1
master:
entityManager:
packages: packageX
datasource:
url: jdbc:mysql://${db-ip}:3306/master
username: root
password: password
tenant:
entityManager:
packages: packageX
datasource:
url-prefix: jdbc:mysql://${db-ip}:3306/
username: root
password: password
hikari:
maximumPoolSize: 2
minimumIdle: 0
idleTimeout: 30000
readreplica:
base-package: packageX.reports
entityManager:
packages: packageX.reports
datasource:
url-prefix: jdbc:mysql://${slave-db-ip}:3306/
username: root
password: password
hikari:
maximumPoolSize: 2
minimumIdle: 0
idleTimeout: 30000
Everything works fine until this point. Now we want to add another datasource that points to a another IP, i.e. Read replica. When I add another PersistenceConfig file such as above, the application fails to start. Below are a new class added. Stack trace is added below as well.
ReadReplicaPersistenceConfig.java
#Log4j2
#Configuration
#EnableJpaRepositories(
basePackages = {"${multitenancy.readreplica.base-package}"},
entityManagerFactoryRef = "readReplicaEntityManagerFactory",
transactionManagerRef = "readReplicaTransactionManager",
includeFilters = #Filter(type = FilterType.ASSIGNABLE_TYPE, value = ReportsRepository.class)
)
#EnableConfigurationProperties(JpaProperties.class)
public class ReadReplicaPersistenceConfig {
private final ConfigurableListableBeanFactory beanFactory;
private final JpaProperties jpaProperties;
private final String entityPackages;
#Autowired
public ReadReplicaPersistenceConfig(
ConfigurableListableBeanFactory beanFactory,
JpaProperties jpaProperties,
#Value("${multitenancy.readreplica.entityManager.packages}")
String entityPackages) {
this.beanFactory = beanFactory;
this.jpaProperties = jpaProperties;
this.entityPackages = entityPackages;
}
#Bean
public LocalContainerEntityManagerFactoryBean readReplicaEntityManagerFactory(
#Qualifier("dynamicDataSourceBasedMultiTenantConnectionProvider") MultiTenantConnectionProvider connectionProvider,
#Qualifier("currentTenantIdentifierResolver") CurrentTenantIdentifierResolver tenantResolver) {
LocalContainerEntityManagerFactoryBean emfBean = new LocalContainerEntityManagerFactoryBean();
emfBean.setPersistenceUnitName("read-db-persistence-unit");
emfBean.setPackagesToScan(entityPackages);
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
emfBean.setJpaVendorAdapter(vendorAdapter);
Map<String, Object> properties = new HashMap<>(this.jpaProperties.getProperties());
properties.put(AvailableSettings.PHYSICAL_NAMING_STRATEGY, "org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy");
properties.put(AvailableSettings.IMPLICIT_NAMING_STRATEGY, "org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy");
properties.put(AvailableSettings.BEAN_CONTAINER, new SpringBeanContainer(this.beanFactory));
properties.put(AvailableSettings.MULTI_TENANT, MultiTenancyStrategy.DATABASE);
properties.put(AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER, connectionProvider);
properties.put(AvailableSettings.MULTI_TENANT_IDENTIFIER_RESOLVER, tenantResolver);
emfBean.setJpaPropertyMap(properties);
return emfBean;
}
#Bean
public JpaTransactionManager readReplicaTransactionManager(
#Qualifier("readReplicaEntityManagerFactory") EntityManagerFactory emf) {
JpaTransactionManager readReplicaTransactionManager = new JpaTransactionManager();
readReplicaTransactionManager.setEntityManagerFactory(emf);
return readReplicaTransactionManager;
}
#Bean
public ReadReplicaDataSource readReplicaDataSource(#Qualifier("dynamicDataSourceBasedMultiTenantConnectionProvider")
MultiTenantConnectionProvider connectionProvider,
#Qualifier("currentTenantIdentifierResolver")
CurrentTenantIdentifierResolver tenantResolver) {
return new ReadReplicaDataSource(connectionProvider, tenantResolver);
}
#Bean
#Primary
public NamedParameterJdbcTemplate namedParameterJdbcTemplateRead(#Qualifier("readReplicaDataSource")
ReadReplicaDataSource readReplicaDataSource) {
return new NamedParameterJdbcTemplate(readReplicaDataSource);
}
#Bean
public JdbcTemplate readReplicaJdbcTemplate(#Qualifier("readReplicaDataSource") ReadReplicaDataSource
readReplicaDataSource) {
return new JdbcTemplate(readReplicaDataSource);
}
}
Summary of the spring.log stacktrace is . Full stacktrace can be found here: https://justpaste.it/6jwhs
[13:20:23.143] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean 'springAsyncConfig' of type [packageX.config.async.SpringAsyncConfig$$EnhancerBySpringCGLIB$$38910a1d] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:23.185] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean 'org.springframework.retry.annotation.RetryConfiguration' of type [org.springframework.retry.annotation.RetryConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:23.245] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean 'org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler#70516d8' of type [org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:23.272] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean '(inner bean)#6c13eb04' of type [org.springframework.beans.factory.config.PropertiesFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:23.273] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean '(inner bean)#6c13eb04' of type [java.util.Properties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:23.276] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean '(inner bean)#18e33fe' of type [org.springframework.data.repository.core.support.PropertiesBasedNamedQueries] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:23.277] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean '(inner bean)#23ba6f2c' of type [org.springframework.data.repository.core.support.RepositoryFragmentsFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:23.278] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean '(inner bean)#23ba6f2c' of type [org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:23.296] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean 'spring.jpa-org.springframework.boot.autoconfigure.orm.jpa.JpaProperties' of type [org.springframework.boot.autoconfigure.orm.jpa.JpaProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:23.297] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean 'tenantPersistenceConfig' of type [packageX.dbframework.hibernateconfig.TenantPersistenceConfig$$EnhancerBySpringCGLIB$$f1fe8a65] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:23.302] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean 'masterDataSourceConfiguration' of type [packageX.dbframework.datasource.MasterDataSourceConfiguration$$EnhancerBySpringCGLIB$$8117359e] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:23.317] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean 'masterDataSourceProperties' of type [org.springframework.boot.autoconfigure.jdbc.DataSourceProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:23.335] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean 'masterDataSource' of type [com.zaxxer.hikari.HikariDataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:23.341] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean 'org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker' of type [org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:23.349] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean '(inner bean)#72ffcc16' of type [org.springframework.beans.factory.config.PropertiesFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:23.349] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean '(inner bean)#72ffcc16' of type [java.util.Properties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:23.349] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean '(inner bean)#72313bde' of type [org.springframework.data.repository.core.support.PropertiesBasedNamedQueries] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:23.350] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean '(inner bean)#5f53b6b2' of type [org.springframework.data.repository.core.support.RepositoryFragmentsFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:23.350] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean '(inner bean)#5f53b6b2' of type [org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:23.353] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean 'masterPersistenceConfig' of type [packageX.dbframework.hibernateconfig.MasterPersistenceConfig$$EnhancerBySpringCGLIB$$540470ad] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:23.494] [restartedMain] [] [] [] [o.h.j.i.u.LogHelper:31] [INFO] - HHH000204: Processing PersistenceUnitInfo [name: master-persistence-unit]
[13:20:23.530] [restartedMain] [] [] [] [o.h.Version:44] [INFO] - HHH000412: Hibernate ORM core version 5.4.27.Final
[13:20:23.638] [restartedMain] [] [] [] [o.h.a.c.Version:56] [INFO] - HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
[13:20:23.735] [restartedMain] [] [] [] [c.z.h.HikariDataSource:110] [INFO] - masterDataSource - Starting...
[13:20:24.041] [restartedMain] [] [] [] [c.z.h.HikariDataSource:123] [INFO] - masterDataSource - Start completed.
[13:20:24.056] [restartedMain] [] [] [] [o.h.d.Dialect:175] [INFO] - HHH000400: Using dialect: org.hibernate.dialect.MySQL57Dialect
[13:20:24.809] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean 'packageX.entityListeners.SyncJobCandidateListener' of type [packageX.entityListeners.SyncJobCandidateListener] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:24.833] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean 'packageX.entityListeners.SyncJobListener' of type [packageX.entityListeners.SyncJobListener] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:27.154] [restartedMain] [] [] [] [o.h.e.t.j.p.i.JtaPlatformInitiator:52] [INFO] - HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
[13:20:27.162] [restartedMain] [] [] [] [o.s.o.j.LocalContainerEntityManagerFactoryBean:437] [INFO] - Initialized JPA EntityManagerFactory for persistence unit 'master-persistence-unit'
[13:20:27.165] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean 'masterEntityManagerFactory' of type [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:27.168] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean 'masterEntityManagerFactory' of type [com.sun.proxy.$Proxy164] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:27.191] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean '(inner bean)#6ada8fd3' of type [com.sun.proxy.$Proxy166] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:27.201] [restartedMain] [] [] [] [o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker:350] [INFO] - Bean 'readReplicaPersistenceConfig' of type [packageX.dbframework.hibernateconfig.ReadReplicaPersistenceConfig$$EnhancerBySpringCGLIB$$759c9f91] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[13:20:27.206] [restartedMain] [] [] [] [o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext:596] [WARN] - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'healthEndpointGroupsBeanPostProcessor' defined in class path resource [org/springframework/boot/actuate/autoconfigure/health/HealthEndpointConfiguration.class]: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration': BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'metaDataSourceAdvisor': Cannot resolve reference to bean 'methodSecurityMetadataSource' while setting constructor argument; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityConfig': Unsatisfied dependency expressed through field 'customRelyingPartyRegistrationRepository'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'customRelyingPartyRegistrationRepository': Unsatisfied dependency expressed through field 'samlRegistrationRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'samlRegistrationRepository' defined in packageX.auth.repository.SamlRegistrationRepository defined in #EnableJpaRepositories declared on TenantPersistenceConfig: Cannot create inner bean '(inner bean)#7a8d7a43' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property 'entityManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#7a8d7a43': Cannot resolve reference to bean 'tenantEntityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'tenantEntityManagerFactory' defined in class path resource [packageXdbframework/hibernateconfig/TenantPersistenceConfig.class]: Unsatisfied dependency expressed through method 'tenantEntityManagerFactory' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dynamicDataSourceBasedMultiTenantConnectionProvider': Unsatisfied dependency expressed through field 'masterTenantRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tenantRepository' defined in packageX.dbframework.datasource.TenantRepository defined in #EnableJpaRepositories declared on MasterPersistenceConfig: Cannot resolve reference to bean 'jpaMappingContext' while setting bean property 'mappingContext'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'readReplicaEntityManagerFactory' defined in class path resource [packageXdbframework/hibernateconfig/ReadReplicaPersistenceConfig.class]: Unsatisfied dependency expressed through method 'readReplicaEntityManagerFactory' parameter 1; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'currentTenantIdentifierResolver': Unsatisfied dependency expressed through field 'tenantRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'packageX.dbframework.datasource.TenantRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
But when I change readReplicaEntityManagerFactory and readReplicaTransactionManager in ReadReplicaPersistenceConfig to tenantEntityManagerFactory and tenantTransactionManager respectively, application starts. Although I have not verified the which database my application is making change to.
I'd appreciate any and all help. Thank you.
I tried using #Lazy, #DependsOn to resolve dependencies to avoid BeanCreationException, but not avail.

To answer my question, I moved TenantRepository, used in DynamicDataSourceBasedMultiTenantConnectionProvider and CurrentTenantIdentifierResolverImpl, into service and lazy loaded that service into these classes, and the application started.
Something like this:
#Service
public class TenantService{
#Autowired
private TenantRepository tenantRepository;
}
public class DynamicDataSourceBasedMultiTenantConnectionProvider {
#Autowired
#Lazy
private TenantService tenantService ;
}
public class CurrentTenantIdentifierResolverImpl {
#Autowired
#Lazy
private TenantService tenantService ;
}

Related

Bean injection not happening even after the presence of bean in Springboot

I am working on Spring project. In this project I have password encoder bean.
#Configuration
public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter {
public AppSecurityConfiguration() {
System.out.println("\n\n " + getClass().getName() + "\n\n\n");
}
#Autowired
private UserService userService;
#Bean
public PasswordEncoder defaultPasswordEncoder() {
System.out.println("\n\n\n bean is created!!!!! \n\n\n");
return new BCryptPasswordEncoder();
}
// other configurations
}
And the class where injection is required is this,
#Component
public class Encoders {
private static PasswordEncoder bCryptPasswordEncoder;
#Autowired
private PasswordEncoder defaultPasswordEncoder;
public Encoders() throws UnsupportedEncodingException {
System.out.println("\n\n\n " + (defaultPasswordEncoder == null) + " \n\n\n"); // this has problem, as defaultPasswordEncoder is null.
Encoders.bCryptPasswordEncoder = defaultPasswordEncoder;
}
// other methods
}
The defaultPasswordEncoder in the above class is null even though I have autowired this field.
The logs are showing that although the appSecurityConfiguration bean was made before encoder bean still the defaultPasswordEncoder bean is being created after encoder bean.
Here is the log,
2021-10-31 10:28:51.644 DEBUG 58508 --- [ restartedMain] o.s.b.f.s.DefaultListableBeanFactory : Creating shared instance of singleton bean 'appSecurityConfiguration'
com.clone.postmanc.security.AppSecurityConfiguration$$EnhancerBySpringCGLIB$$9529a353
.
.
.
.
2021-10-31 10:28:51.695 DEBUG 58508 --- [ restartedMain] o.s.b.f.s.DefaultListableBeanFactory : Creating shared instance of singleton bean 'encoders'
true // coming from Encoder#Encoder showing that
// defaultPasswordEncoder bean is null
2021-10-31 10:28:51.697 DEBUG 58508 --- [ restartedMain] o.s.b.f.s.DefaultListableBeanFactory : Creating shared instance of singleton bean 'defaultPasswordEncoder'
bean is created!!!!! // coming from AppSecurityConfiguration#defaultPasswordEncoder
I have also tried depends on annotation,
#Component
#DependsOn("defaultPasswordEncoder")
public class Encoders {
// rest is same
}
Now in logs defaultPasswordEncoder bean is being created before encoders but still the injection is not happening and the PasswordEncoder defaultPasswordEncoder field is null.
Here is the log,
2021-10-31 10:28:51.644 DEBUG 58508 --- [ restartedMain] o.s.b.f.s.DefaultListableBeanFactory : Creating shared instance of singleton bean 'appSecurityConfiguration'
com.clone.postmanc.security.AppSecurityConfiguration$$EnhancerBySpringCGLIB$$9529a353
.
.
.
2021-10-31 10:51:27.323 DEBUG 59592 --- [ restartedMain] o.s.b.f.s.DefaultListableBeanFactory : Creating shared instance of singleton bean 'defaultPasswordEncoder'
bean is created!!!!!
2021-10-31 10:51:27.327 DEBUG 59592 --- [ restartedMain] o.s.b.f.s.DefaultListableBeanFactory : Creating shared instance of singleton bean 'encoders'
true // still the field is null.
Can someone tell what is happening? And to resolve this issue?
Use constructor injection instead of property injection
public Encoders(PasswordEncoder defaultPasswordEncoder)
Then the bean will be available in constructor.

Spring + Hibernate without XML. Error: NoSuchBeanDefinitionException

I'm learning Spring and Hibernate on my own. I have read few articles and tried to create Spring and Hibernate application without XML at all. I don't know why, but it doesn't work and in the end I get Error message:
17:28:32.845 [main] DEBUG org.springframework.core.env.StandardEnvironment - Adding [systemProperties] PropertySource with lowest search precedence
17:28:32.854 [main] DEBUG org.springframework.core.env.StandardEnvironment - Adding [systemEnvironment] PropertySource with lowest search precedence
17:28:32.854 [main] DEBUG org.springframework.core.env.StandardEnvironment - Initialized StandardEnvironment with PropertySources [systemProperties,systemEnvironment]
17:28:32.928 [main] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning
17:28:32.931 [main] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - JSR-330 'javax.inject.Named' annotation found and supported for component scanning
17:28:32.937 [main] DEBUG org.springframework.core.io.support.PathMatchingResourcePatternResolver - Resolved classpath location [com/boris/] to resources []
17:28:32.937 [main] DEBUG org.springframework.core.io.support.PathMatchingResourcePatternResolver - Resolved location pattern [classpath*:com/boris/**/*.class] to resources []
17:28:32.944 [main] INFO org.springframework.context.annotation.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext#7382f612: startup date [Mon Aug 14 17:28:32 EEST 2017]; root of context hierarchy
17:28:32.946 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Bean factory for org.springframework.context.annotation.AnnotationConfigApplicationContext#7382f612: org.springframework.beans.factory.support.DefaultListableBeanFactory#5702b3b1: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory]; root of factory hierarchy
17:28:32.965 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
17:28:32.966 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
17:28:33.003 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Eagerly caching bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor' to allow for resolving potential circular references
17:28:33.009 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
17:28:33.065 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
17:28:33.065 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
17:28:33.067 [main] INFO org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
17:28:33.067 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Eagerly caching bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor' to allow for resolving potential circular references
17:28:33.067 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
17:28:33.068 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalRequiredAnnotationProcessor'
17:28:33.074 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'org.springframework.context.annotation.internalRequiredAnnotationProcessor'
17:28:33.091 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Eagerly caching bean 'org.springframework.context.annotation.internalRequiredAnnotationProcessor' to allow for resolving potential circular references
17:28:33.091 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'org.springframework.context.annotation.internalRequiredAnnotationProcessor'
17:28:33.092 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
17:28:33.092 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
17:28:33.109 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Eagerly caching bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor' to allow for resolving potential circular references
17:28:33.109 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
17:28:33.109 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalPersistenceAnnotationProcessor'
17:28:33.109 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'org.springframework.context.annotation.internalPersistenceAnnotationProcessor'
17:28:33.111 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Eagerly caching bean 'org.springframework.context.annotation.internalPersistenceAnnotationProcessor' to allow for resolving potential circular references
17:28:33.111 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'org.springframework.context.annotation.internalPersistenceAnnotationProcessor'
17:28:33.111 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor'
17:28:33.111 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor'
17:28:33.112 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Eagerly caching bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor' to allow for resolving potential circular references
17:28:33.112 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor'
17:28:33.112 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor'
17:28:33.112 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor'
17:28:33.114 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Eagerly caching bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor' to allow for resolving potential circular references
17:28:33.114 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor'
17:28:33.119 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Unable to locate MessageSource with name 'messageSource': using default [org.springframework.context.support.DelegatingMessageSource#27808f31]
17:28:33.126 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Unable to locate ApplicationEventMulticaster with name 'applicationEventMulticaster': using default [org.springframework.context.event.SimpleApplicationEventMulticaster#6b57696f]
17:28:33.127 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#5702b3b1: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor]; root of factory hierarchy
17:28:33.127 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
17:28:33.127 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
17:28:33.127 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.context.annotation.internalRequiredAnnotationProcessor'
17:28:33.127 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
17:28:33.127 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.context.annotation.internalPersistenceAnnotationProcessor'
17:28:33.128 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerProcessor'
17:28:33.128 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'org.springframework.context.event.internalEventListenerProcessor'
17:28:33.140 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Eagerly caching bean 'org.springframework.context.event.internalEventListenerProcessor' to allow for resolving potential circular references
17:28:33.187 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'org.springframework.context.event.internalEventListenerProcessor'
17:28:33.187 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerFactory'
17:28:33.187 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'org.springframework.context.event.internalEventListenerFactory'
17:28:33.188 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Eagerly caching bean 'org.springframework.context.event.internalEventListenerFactory' to allow for resolving potential circular references
17:28:33.196 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'org.springframework.context.event.internalEventListenerFactory'
17:28:33.196 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor'
17:28:33.197 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor'
17:28:33.197 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.context.event.internalEventListenerFactory'
17:28:33.248 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Unable to locate LifecycleProcessor with name 'lifecycleProcessor': using default [org.springframework.context.support.DefaultLifecycleProcessor#2641e737]
17:28:33.249 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'lifecycleProcessor'
17:28:33.252 [main] DEBUG org.springframework.core.env.PropertySourcesPropertyResolver - Searching for key 'spring.liveBeansView.mbeanDomain' in [systemProperties]
17:28:33.252 [main] DEBUG org.springframework.core.env.PropertySourcesPropertyResolver - Searching for key 'spring.liveBeansView.mbeanDomain' in [systemEnvironment]
17:28:33.253 [main] DEBUG org.springframework.core.env.PropertySourcesPropertyResolver - Could not find key 'spring.liveBeansView.mbeanDomain' in any property source. Returning [null]
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'employeeService' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:698)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1175)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1060)
at Test.main(Test.java:18)
org.springframework.context.annotation.AnnotationConfigApplicationContext#7382f612: startup date [Mon Aug 14 17:28:32 EEST 2017]; root of context hierarchy
Process finished with exit code 1
I'm trying to find what I did wrong. But unfortunately I don't find anything wrong in my code. Could you please help me?
Here's my full code below.
AppConfig
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.ClassPathResource;
#Import({RepositoryConfig.class})
#Configuration
public class AppConfig
{
#Bean
public PropertyPlaceholderConfigurer getPropertyPlaceholderConfigurer()
{
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
ppc.setLocation(new ClassPathResource("application.properties"));
ppc.setIgnoreUnresolvablePlaceholders(true);
return ppc;
}
}
Emloyee
import javax.persistence.*;
#Entity
#Table(name = "tasks_test.employee_example")
public class Employee {
#Id #GeneratedValue
#Column(name = "id")
private int id;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "salary")
private int salary;
public Employee() {}
public Employee(Integer id, String firstName, String lastName, int salary)
{
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.salary = salary;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
public int getSalary() {
return salary;
}
public void setSalary( int salary ) {
this.salary = salary;
}
#Override
public String toString()
{
return "User [firstName=" + firstName + ", lastName=" + lastName + ", id=" + id + ", salary=" + salary+ "]";
}
}
EmployeeRepository
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate4.HibernateTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
#Transactional
#Repository
public class EmployeeRepository
{
#Autowired
private HibernateTemplate hibernateTemplate;
public List<Employee> getAllEmployees()
{
return this.hibernateTemplate.loadAll(Employee.class);
}
public Integer createEmployee(Employee employee)
{
Employee mergeEmployee = this.hibernateTemplate.merge(employee);
return mergeEmployee.getId();
}
}
EmployeeService
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
#Service
public class EmployeeService
{
#Autowired
private EmployeeRepository employeeRepository;
public List<Employee> getAllEmployees()
{
return this.employeeRepository.getAllEmployees();
}
public Integer createEmployee(Employee employee)
{
return this.employeeRepository.createEmployee(employee);
}
}
RepositoryConfig
import java.util.Properties;
import javax.sql.DataSource;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTemplate;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
#Configuration
public class RepositoryConfig
{
#Value("${jdbc.driverClassName}") private String driverClassName;
#Value("${jdbc.url}") private String url;
#Value("${jdbc.username}") private String username;
#Value("${jdbc.password}") private String password;
#Value("${hibernate.dialect}") private String hibernateDialect;
#Value("${hibernate.show_sql}") private String hibernateShowSql;
#Value("${hibernate.hbm2ddl.auto}") private String hibernateHbm2ddlAuto;
#Bean()
public DataSource getDataSource()
{
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName(driverClassName);
ds.setUrl(url);
ds.setUsername(username);
ds.setPassword(password);
return ds;
}
#Bean
#Autowired
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory)
{
HibernateTransactionManager htm = new HibernateTransactionManager();
htm.setSessionFactory(sessionFactory);
return htm;
}
#Bean
#Autowired
public HibernateTemplate getHibernateTemplate(SessionFactory sessionFactory)
{
HibernateTemplate hibernateTemplate = new HibernateTemplate(sessionFactory);
return hibernateTemplate;
}
#Bean
public LocalSessionFactoryBean getSessionFactory()
{
LocalSessionFactoryBean asfb = new LocalSessionFactoryBean();
asfb.setDataSource(getDataSource());
asfb.setHibernateProperties(getHibernateProperties());
asfb.setPackagesToScan(new String[]{"com.boris"});
return asfb;
}
#Bean
public Properties getHibernateProperties()
{
Properties properties = new Properties();
properties.put("hibernate.dialect", hibernateDialect);
properties.put("hibernate.show_sql", hibernateShowSql);
properties.put("hibernate.hbm2ddl.auto", hibernateHbm2ddlAuto);
return properties;
}
}
Test
import java.util.List;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
#ComponentScan("com.boris")
public class Test
{
public static void main(String[] args)
{
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.scan("com.boris");
ctx.refresh();
System.out.println(ctx);
EmployeeService employeeService = ctx.getBean("employeeService",EmployeeService.class);
Employee employee1 = new Employee(null, "Bob", "Marley", 16000);
Employee employee2 = new Employee(null, "Donald", "Trump", 12000);
Employee employee3 = new Employee(null, "Olga","Lifshitz", 8000);
Employee employee4 = new Employee(null, "Massimo", "Dutti", 7000);
int id1 = employeeService.createEmployee(employee1);
System.out.println("New Employee created with ID="+id1);
int id2 = employeeService.createEmployee(employee2);
System.out.println("New Employee created with ID="+id2);
int id3 = employeeService.createEmployee(employee3);
System.out.println("New Employee created with ID="+id3);
int id4 = employeeService.createEmployee(employee4);
System.out.println("New Employee created with ID="+id4);
List<Employee> everybody = employeeService.getAllEmployees();
for (Employee e : everybody)
{
System.out.println(e);
}
}
}
application.properties
jdbc.driverClassName=org.hsqldb.jdbcDriver
jdbc.url=jdbc:mysql://localhost:3306/tasks_test
jdbc.username=user
jdbc.password=pass
hibernate.dialect=org.hibernate.dialect.HSQLDialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=update
hibernate.generate_statistics=true
Can you try to initialize employeeService like that
#Autowired EmployeeService employeeService
on Test class.

APPLICATION FAILED TO START (Spring MockMvc #WebMvcTest)

everyone. I am new to WebMvcTest, and am learning to write a PostControllerTest. While the project runs well, the test does not work.
2017-05-31 10:08:09.490 INFO 5768 --- [ main] nz.p2.controller.PostControllerTest : Starting PostControllerTest on My-PC with PID 5768 (started by Me in C:\...)
2017-05-31 10:08:09.491 INFO 5768 --- [ main] nz.p2.controller.PostControllerTest : No active profile set, falling back to default profiles: default
2017-05-31 10:08:10.989 INFO 5768 --- [ main] o.s.w.c.s.GenericWebApplicationContext : Refreshing org.springframework.web.context.support.GenericWebApplicationContext#2a8d39c4: startup date [Wed May 31 10:08:10 NZST 2017]; root of context hierarchy
2017-05-31 10:08:12.788 INFO 5768 --- [ main] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
2017-05-31 10:08:13.311 WARN 5768 --- [ main] o.s.w.c.s.GenericWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'reCaptchaAuthenticationFilter': Unsatisfied dependency expressed through field 'reCaptchaService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'nz.p2.captcha.ReCaptchaService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
2017-05-31 10:08:13.326 INFO 5768 --- [ main] utoConfigurationReportLoggingInitializer :
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2017-05-31 10:08:13.534 ERROR 5768 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Field reCaptchaService in nz.p2.captcha.ReCaptchaAuthenticationFilter required a bean of type 'nz.p2.captcha.ReCaptchaService' that could not be found.
Action:
Consider defining a bean of type 'nz.p2.captcha.ReCaptchaService' in your configuration.
It tells me to do something with the ReCaptchaService; which isn't used with the PostController. Given the simplifed Controller class:
#Controller
public class PostController {
#Autowired
private PostService postService;
#RequestMapping(value = URI_POST_POST, method = RequestMethod.GET)
public ModelAndView get(#Valid Long mkid) throws IOException {
// do somthing here using postService;
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName(URI_POST_POST);
modelAndView.addObject("abc", abc);
return modelAndView;
}
}
The PostControllerTest class is here:
#RunWith(SpringRunner.class)
#WebMvcTest(controllers = PostController.class)
public class PostControllerTest {
private MockMvc mockMvc;
#Autowired
private WebApplicationContext webApplicationContext;
#MockBean
private PostController postControllereMock;
#Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.standaloneSetup(webApplicationContext).build();
}
#Test
public void testList() throws Exception {
assertThat(this.postControllereMock).isNotNull();
mockMvc.perform(MockMvcRequestBuilders.get(URI_POST_POST + "?mkid=8044022272730561994"))
.andExpect(status().isOk())
.andExpect(content().contentType("text/html;charset=UTF-8"))
.andExpect(view().name(URI_POST_POST))
.andExpect(MockMvcResultMatchers.view().name(URI_POST_POST))
.andExpect(content().string(Matchers.containsString("I have put together some image galleries")))
.andDo(print());
}
}
I have to mention that the reCaptchaService is #Autowired in the ReCaptchaAuthenticationFilter, and the latter one is #Autowired and used here:
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.
// tl; nw
.and().csrf().disable()
.addFilterBefore(reCaptchaAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
// tl; nw
}
}
So, in this case, how can I test the PostController?

Setting up H2 database in Spring + Hibernate without XML File yields NullPointerException

I have a problem regarding the proper setup of a H2 database in springboot + hibernate and would very much appreciate your help. I guess my problem is in the #Transaction Annotation, since the respective class throws a NullPointerException. Here is some background information:
The idea of the program (which is not yet finished) is that agents (class "AgentLogic") can calulate prices for specific tasks within a Multi-Agent System. In order to calculate the price, an agent draws parameters from a database. These parameters are needed for some Machine Learning algorithms (in class "MachineLearningSource"), which will calculate the price of the agent.
I would like to setup the configuration of the database WITHOUT using an XML File, similar to the example in http://www.baeldung.com/hibernate-4-spring
The project has the following structure:
Project Structure
UPDATED CODE AFTER INCORPORATING CHANGES FROM #StanislavL
The project is implemented in SpringBoot. Accordingly, I use the following Application class:
package org.schlago.mldb;
import...
#SpringBootApplication
public class Application {
public static void main(String[] args) {
// ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
SpringApplicationBuilder builder = new SpringApplicationBuilder(Application.class);
builder.headless(false);
ConfigurableApplicationContext context = builder.run(args);
}
}
The following class contains the configuration of the database in Spring Hibernate, called DataBaseConfig:
package org.schlago.mldb.database;
import...
#Configuration
#Profile("param_db")
#EnableTransactionManagement
#ComponentScan({"org.schlago.mldb.mapping","org.schlago.mldb.machineLearning"})
public class DatabaseConfig {
#Autowired
private Environment env;
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("datasource.driver"));
dataSource.setUrl(env.getProperty("datasource.url"));
dataSource.setUsername(env.getProperty("datasource.username"));
dataSource.setPassword(env.getProperty("datasource.password"));
return dataSource;
}
#Bean
public LocalSessionFactoryBean sessionFactory(){
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
sessionFactoryBean.setPackagesToScan(env.getProperty("entitymanager.packagesToScan"));
Properties hibernateProperties = new Properties();
hibernateProperties.put("hibernate.dialect", env.getProperty("jpa.hibernate.dialect"));
hibernateProperties.put("hibernate.show_sql", env.getProperty("jpa.hibernate.show-sql"));
hibernateProperties.put("hibernate.hbm2ddl.auto", env.getProperty("jpa.hibernate.hbm2ddl.auto"));
hibernateProperties.put("spring.jpa.hibernate.ddl-auto", env.getProperty("jpa.hibernate.ddl-auto"));
sessionFactoryBean.setHibernateProperties(hibernateProperties);
return sessionFactoryBean;
}
#Bean
#Autowired
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory){
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory);
return transactionManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
}
This configuration uses the following environment (#Profile) in order to setup the sessionFactoryBean, called appliation.yaml:
spring.profiles: param_db
datasource:
driver: org.h2.Driver
url: jdbc:h2:tcp://localhost/~/test
username: sa
password:
jpa:
hibernate.show-sql: true
hibernate.hbm2ddl.auto: none
hibernate.dialect: org.hibernate.dialect.H2Dialect
hibernate.ddl-auto: validate
hibernate.globally_quoted_identifiers: true
entitymanager:
packagesToScan: org.schlago.mldb.mapping
Parameters shall be inserted to the database via a DAO, using a #Transactional Annotation. This DAO is called ParametersDao:
package org.schlago.mldb.mapping;
import ...
#Transactional
public class ParametersDao {
#Autowired
private SessionFactory _sessionFactory;
private Session getSession() {
return _sessionFactory.getCurrentSession();
}
public void save(Parameters parameters) { getSession().save(parameters); }
public void update(Parameters parameters) {
getSession().update(parameters);
}
public List<Parameters> getAllParameters() {
return getSession().createQuery("from Parameters").list();
}
public Parameters getParameterById(int id) {
List<Parameters> parametersList = getSession()
.createQuery("from Parameters where paramId = :theId")
.setParameter("theId", id).list();
if (parametersList.size() == 0) {
return null;
}
return parametersList.get(0);
}
}
Parameters are specified via the Paramters class:
package org.schlago.mldb.mapping;
#Entity
#Table(name = "mlparam")
public class Parameters {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long paramId;
#Column(name = "name")
private String name;
#Column(name = "value")
private double value;
#Column(name = "timestamp")
private Date timestamp;
public Parameters(){
}
public long getParamId() {
return paramId;
}
public void setParamId(int paramId) {
this.paramId = paramId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getValue() {
return value;
}
public void setValue(double value) {
this.value = value;
}
public Date getTimestamp() {
return timestamp;
}
public void setTimestamp(Date timestamp) { this.timestamp = timestamp; }
}
I think there is an error in the way ParametersDao is setup. However, for your better understanding, here are the other classes used within this project. The following class is AgentLogic, which will calculate a price upon request in a later strange of the code. Since the code is still in an early stage, I used #PostConstruct rather than a request, in order to test if the price calulation works:
package org.schlago.mldb.logic;
import...
#Component
public class AgentLogic {
private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);
#Autowired
private MachineLearningSource machineLearningSource;
#PostConstruct
public void init(){
int priceInCent = 50;
priceInCent = machineLearningSource.getPrice(getAgent());
LOGGER.info("Answered with offer about " + priceInCent + " Cents.");
}
// DUMMY class: Return a new agent
public static Agent getAgent(){
// Currently, an Agent is just an (empty) dummy class
Agent agent = new Agent();
return agent;
}
}
Finally, the following class is responsible for price calcuation. Since the code is still in an early stage, price calculation is set randomly, rather than implementing machinelearning algorithms. In the method getParameters(), some Parameters are inserted to the dataBase for testing purposes:
package org.schlago.mldb.machineLearning;
import org.schlago.mldb.Nodes.Agent;
import org.schlago.mldb.mapping.Parameters;
import org.schlago.mldb.mapping.ParametersDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Date;
import java.util.HashMap;
import java.util.Random;
#Component
public class MachineLearningSource {
#Autowired
ParametersDao parametersDao;
private static final Logger LOGGER = LoggerFactory.getLogger(MachineLearningSource.class);
public int getPrice(Agent agent) {
Random r = new Random();
int thePrice = r.nextInt(99) + 1;
LOGGER.info("The price is dynamically calculated right now!");
HashMap<String, Double> parameters = getParameters();
return thePrice;
}
public HashMap<String, Double> getParameters() {
HashMap<String, Double> equationParameters = new HashMap<>();
// TEST: Since database is currently empty, parameters are inserted manually here (this will change later)
LOGGER.info("About to insert into table");
Parameters myCalcParams = new Parameters();
myCalcParams.setName("kappa");
myCalcParams.setValue(2.39583992);
myCalcParams.setTimestamp(new Date());
parametersDao.save(myCalcParams);
LOGGER.info("Successfully inserted parameters");
/*
// Get the parameters via parametersDao, work in progress!
List<Parameters> parameters = parametersDao.getAllParameters();
Parameters myParam = parametersDao.getParameterById(3748);
if (myParam == null) {
LOGGER.info("Dataset does not exist!");
}
for (Parameters param : parameters) {
equationParameters.put(param.getName(), param.getValue());
LOGGER.info("Actual parameter for price calculation: " + param.getName());
LOGGER.info("Value: " + param.getValue());
}
*/
// TEST: Return dummy equationParameters
equationParameters.put("a", 2.48238948239);
equationParameters.put("b", 8.23482489729);
return equationParameters;
}
}
UPDATED ERROR STATEMENT
Unfortuntely, I still get an error:
2017-02-03 14:41:39.005 INFO 7416 --- [ main] org.schlago.mldb.Application : Starting Application on mobile-97 with PID 7416 (C:\Users\Jan\Documents\Masterarbeit\12_MLDBtest\target\classes started by Jan in C:\Users\Jan\Documents\Masterarbeit\12_MLDBtest)
2017-02-03 14:41:39.005 INFO 7416 --- [ main] org.schlago.mldb.Application : The following profiles are active: param_db
2017-02-03 14:41:39.083 INFO 7416 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext#79ca92b9: startup date [Fri Feb 03 14:41:39 CET 2017]; root of context hierarchy
2017-02-03 14:41:40.581 INFO 7416 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'databaseConfig' of type [class org.schlago.mldb.database.DatabaseConfig$$EnhancerBySpringCGLIB$$829d3967] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-02-03 14:41:40.721 INFO 7416 --- [ main] o.s.j.d.DriverManagerDataSource : Loaded JDBC driver: org.h2.Driver
2017-02-03 14:41:41.004 INFO 7416 --- [ main] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'default'
2017-02-03 14:41:41.020 INFO 7416 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [
name: default
...]
2017-02-03 14:41:41.129 INFO 7416 --- [ main] org.hibernate.Version : HHH000412: Hibernate Core {4.3.11.Final}
2017-02-03 14:41:41.129 INFO 7416 --- [ main] org.hibernate.cfg.Environment : HHH000206: hibernate.properties not found
2017-02-03 14:41:41.129 INFO 7416 --- [ main] org.hibernate.cfg.Environment : HHH000021: Bytecode provider name : javassist
2017-02-03 14:41:41.394 INFO 7416 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
2017-02-03 14:41:41.521 INFO 7416 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
2017-02-03 14:41:41.693 INFO 7416 --- [ main] o.h.h.i.ast.ASTQueryTranslatorFactory : HHH000397: Using ASTQueryTranslatorFactory
2017-02-03 14:41:42.363 INFO 7416 --- [ main] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000227: Running hbm2ddl schema export
2017-02-03 14:41:42.432 INFO 7416 --- [ main] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000230: Schema export complete
2017-02-03 14:41:42.510 WARN 7416 --- [ main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'agentLogic': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.schlago.mldb.machineLearning.MachineLearningSource org.schlago.mldb.logic.AgentLogic.machineLearningSource; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'machineLearningSource': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.schlago.mldb.mapping.ParametersDao org.schlago.mldb.machineLearning.MachineLearningSource.parametersDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.schlago.mldb.mapping.ParametersDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
2017-02-03 14:41:42.510 INFO 7416 --- [ main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2017-02-03 14:41:42.510 INFO 7416 --- [ main] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000227: Running hbm2ddl schema export
2017-02-03 14:41:42.559 INFO 7416 --- [ main] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000230: Schema export complete
2017-02-03 14:41:42.559 ERROR 7416 --- [ main] o.s.boot.SpringApplication : Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'agentLogic': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.schlago.mldb.machineLearning.MachineLearningSource org.schlago.mldb.logic.AgentLogic.machineLearningSource; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'machineLearningSource': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.schlago.mldb.mapping.ParametersDao org.schlago.mldb.machineLearning.MachineLearningSource.parametersDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.schlago.mldb.mapping.ParametersDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.schlago.mldb.machineLearning.MachineLearningSource org.schlago.mldb.logic.AgentLogic.machineLearningSource; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'machineLearningSource': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.schlago.mldb.mapping.ParametersDao org.schlago.mldb.machineLearning.MachineLearningSource.parametersDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.schlago.mldb.mapping.ParametersDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'machineLearningSource': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.schlago.mldb.mapping.ParametersDao org.schlago.mldb.machineLearning.MachineLearningSource.parametersDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.schlago.mldb.mapping.ParametersDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.schlago.mldb.mapping.ParametersDao org.schlago.mldb.machineLearning.MachineLearningSource.parametersDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.schlago.mldb.mapping.ParametersDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations:
2017-02-03 14:41:42.575 INFO 7416 --- [ main] .b.l.ClasspathLoggingApplicationListener : Application failed to start with classpath: [file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/charsets.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/deploy.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/ext/access-bridge-64.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/ext/cldrdata.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/ext/dnsns.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/ext/jaccess.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/ext/jfxrt.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/ext/localedata.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/ext/nashorn.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/ext/sunec.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/ext/sunjce_provider.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/ext/sunmscapi.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/ext/sunpkcs11.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/ext/zipfs.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/javaws.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/jce.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/jfr.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/jfxswt.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/jsse.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/management-agent.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/plugin.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/resources.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/rt.jar, file:/C:/Users/Jan/Documents/Masterarbeit/12_MLDBtest/target/classes/, file:/C:/Users/Jan/.m2/repository/org/springframework/boot/spring-boot-starter-data-jpa/1.3.5.RELEASE/spring-boot-starter-data-jpa-1.3.5.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/boot/spring-boot-starter/1.3.5.RELEASE/spring-boot-starter-1.3.5.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/boot/spring-boot/1.3.5.RELEASE/spring-boot-1.3.5.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/1.3.5.RELEASE/spring-boot-autoconfigure-1.3.5.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/boot/spring-boot-starter-logging/1.3.5.RELEASE/spring-boot-starter-logging-1.3.5.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/ch/qos/logback/logback-classic/1.1.7/logback-classic-1.1.7.jar, file:/C:/Users/Jan/.m2/repository/ch/qos/logback/logback-core/1.1.7/logback-core-1.1.7.jar, file:/C:/Users/Jan/.m2/repository/org/slf4j/jul-to-slf4j/1.7.21/jul-to-slf4j-1.7.21.jar, file:/C:/Users/Jan/.m2/repository/org/slf4j/log4j-over-slf4j/1.7.21/log4j-over-slf4j-1.7.21.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/spring-core/4.2.6.RELEASE/spring-core-4.2.6.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/yaml/snakeyaml/1.16/snakeyaml-1.16.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/boot/spring-boot-starter-aop/1.3.5.RELEASE/spring-boot-starter-aop-1.3.5.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/spring-aop/4.2.6.RELEASE/spring-aop-4.2.6.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/aopalliance/aopalliance/1.0/aopalliance-1.0.jar, file:/C:/Users/Jan/.m2/repository/org/aspectj/aspectjweaver/1.8.9/aspectjweaver-1.8.9.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/boot/spring-boot-starter-jdbc/1.3.5.RELEASE/spring-boot-starter-jdbc-1.3.5.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/apache/tomcat/tomcat-jdbc/8.0.33/tomcat-jdbc-8.0.33.jar, file:/C:/Users/Jan/.m2/repository/org/apache/tomcat/tomcat-juli/8.0.33/tomcat-juli-8.0.33.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/spring-jdbc/4.2.6.RELEASE/spring-jdbc-4.2.6.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/hibernate/hibernate-entitymanager/4.3.11.Final/hibernate-entitymanager-4.3.11.Final.jar, file:/C:/Users/Jan/.m2/repository/org/jboss/logging/jboss-logging/3.3.0.Final/jboss-logging-3.3.0.Final.jar, file:/C:/Users/Jan/.m2/repository/org/jboss/logging/jboss-logging-annotations/1.2.0.Beta1/jboss-logging-annotations-1.2.0.Beta1.jar, file:/C:/Users/Jan/.m2/repository/org/hibernate/hibernate-core/4.3.11.Final/hibernate-core-4.3.11.Final.jar, file:/C:/Users/Jan/.m2/repository/antlr/antlr/2.7.7/antlr-2.7.7.jar, file:/C:/Users/Jan/.m2/repository/org/jboss/jandex/1.1.0.Final/jandex-1.1.0.Final.jar, file:/C:/Users/Jan/.m2/repository/dom4j/dom4j/1.6.1/dom4j-1.6.1.jar, file:/C:/Users/Jan/.m2/repository/xml-apis/xml-apis/1.0.b2/xml-apis-1.0.b2.jar, file:/C:/Users/Jan/.m2/repository/org/hibernate/common/hibernate-commons-annotations/4.0.5.Final/hibernate-commons-annotations-4.0.5.Final.jar, file:/C:/Users/Jan/.m2/repository/org/hibernate/javax/persistence/hibernate-jpa-2.1-api/1.0.0.Final/hibernate-jpa-2.1-api-1.0.0.Final.jar, file:/C:/Users/Jan/.m2/repository/org/javassist/javassist/3.18.1-GA/javassist-3.18.1-GA.jar, file:/C:/Users/Jan/.m2/repository/javax/transaction/javax.transaction-api/1.2/javax.transaction-api-1.2.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/data/spring-data-jpa/1.9.4.RELEASE/spring-data-jpa-1.9.4.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/data/spring-data-commons/1.11.4.RELEASE/spring-data-commons-1.11.4.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/spring-orm/4.2.6.RELEASE/spring-orm-4.2.6.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/spring-context/4.2.6.RELEASE/spring-context-4.2.6.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/spring-expression/4.2.6.RELEASE/spring-expression-4.2.6.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/spring-tx/4.2.6.RELEASE/spring-tx-4.2.6.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/spring-beans/4.2.6.RELEASE/spring-beans-4.2.6.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/slf4j/jcl-over-slf4j/1.7.21/jcl-over-slf4j-1.7.21.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/spring-aspects/4.2.6.RELEASE/spring-aspects-4.2.6.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/com/sparkjava/spark-core/1.1.1/spark-core-1.1.1.jar, file:/C:/Users/Jan/.m2/repository/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar, file:/C:/Users/Jan/.m2/repository/org/eclipse/jetty/jetty-server/9.2.16.v20160414/jetty-server-9.2.16.v20160414.jar, file:/C:/Users/Jan/.m2/repository/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar, file:/C:/Users/Jan/.m2/repository/org/eclipse/jetty/jetty-http/9.2.16.v20160414/jetty-http-9.2.16.v20160414.jar, file:/C:/Users/Jan/.m2/repository/org/eclipse/jetty/jetty-util/9.2.16.v20160414/jetty-util-9.2.16.v20160414.jar, file:/C:/Users/Jan/.m2/repository/org/eclipse/jetty/jetty-io/9.2.16.v20160414/jetty-io-9.2.16.v20160414.jar, file:/C:/Users/Jan/.m2/repository/org/eclipse/jetty/jetty-webapp/9.2.16.v20160414/jetty-webapp-9.2.16.v20160414.jar, file:/C:/Users/Jan/.m2/repository/org/eclipse/jetty/jetty-xml/9.2.16.v20160414/jetty-xml-9.2.16.v20160414.jar, file:/C:/Users/Jan/.m2/repository/org/eclipse/jetty/jetty-servlet/9.2.16.v20160414/jetty-servlet-9.2.16.v20160414.jar, file:/C:/Users/Jan/.m2/repository/org/eclipse/jetty/jetty-security/9.2.16.v20160414/jetty-security-9.2.16.v20160414.jar, file:/C:/Users/Jan/.m2/repository/net/sf/xenqtt/xenqtt/0.9.7/xenqtt-0.9.7.jar, file:/C:/Users/Jan/.m2/repository/org/json/json/20151123/json-20151123.jar, file:/C:/Users/Jan/.m2/repository/com/pi4j/pi4j-core/1.0/pi4j-core-1.0.jar, file:/C:/Users/Jan/.m2/repository/org/bouncycastle/bcprov-jdk15on/1.54/bcprov-jdk15on-1.54.jar, file:/C:/Users/Jan/.m2/repository/org/bouncycastle/bcpkix-jdk15on/1.54/bcpkix-jdk15on-1.54.jar, file:/C:/Users/Jan/.m2/repository/com/h2database/h2/1.4.192/h2-1.4.192.jar, file:/C:/Users/Jan/.m2/repository/org/opcfoundation/ua/1.02.337.10/ua-1.02.337.10.jar, file:/C:/Users/Jan/.m2/repository/com/prosys/ua/server-client-sdk/2.2/server-client-sdk-2.2.jar, file:/C:/Program%20Files%20(x86)/JetBrains/IntelliJ%20IDEA%202016.2.5/lib/idea_rt.jar]
Try to add #Component annotation to the MachineLearningSource service class and check both dao and the service are included in the #ComponentScan
UPDATE
In the AgentLogic you manually create the machineLearningSource
MachineLearningSource machineLearningSource = new MachineLearningSource();
priceInCent = machineLearningSource.getPrice(getAgent());
Instead add
#Autowired
private MachineLearningSource machineLearningSource;
To the class to let Spring initialize this properly. Or you can autowire dao in the class and manually call
machineLearningSource.setDao(theAutowiredDao);
UPDATE2:
Now the dao is not marked to be detected as a spring bean. Add #Repository annotation to the DAO.
UPDATE3:
sessionFactoryBean.setPackagesToScan(env.getProperty("entitymanager.packagesToScan"));
check which exactly packages are scanned there. Need to have all packages where your entity classes are stored.

Did not find handler method

I am trying to invoke a rest endpoint, but getting this info when i call it, resulting in a 404 error in UI
2016-08-07 13:43:42.611 DEBUG 27834 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /api/v1/operations
2016-08-07 13:43:42.614 DEBUG 27834 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/api/v1/operations]
2016-08-07 13:43:42.615 DEBUG 27834 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Matching patterns for request [/api/v1/operations] are [/**]
2016-08-07 13:43:42.616 DEBUG 27834 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : URI Template variables for request [/api/v1/operations] are {}
2016-08-07 13:43:42.617 DEBUG 27834 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapping [/api/v1/operations] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver#39ead1b7]]] and 1 interceptor
There are 2 controller class in the same package with different endpoint
#RestController
public class OperationRetrievalController {
#Autowired
OperationRetrievalManager operationRetrievalManager;
private static Logger logger = Logger.getLogger(OperationRetrievalController.class);
#RequestMapping("/api/v1/operations")
public ResponseEntity<List<OperationView>> requestUserOperations() {
String ssoId = "xxxxxx";
logger.info("Inside request operationRetrivel Manager +++++++++>>>>>>>>");
return new ResponseEntity<List<OperationView>>(operationRetrievalManager.retrieveOperations(ssoId), HttpStatus.OK);
}
}
I have another class in the same package :
#RestController
public class ComponentRetrievalController {
#Autowired
ComponentRetrievalManager componentRetrievalManager;
#RequestMapping(value = "api/v1/component/{sso_id}" , method=RequestMethod.GET)
public ResponseEntity<List<Component>> requestUserComponent(#PathVariable("sso_id") String ssoId) {
return new ResponseEntity<List<Component>>(componentRetrievalManager.retrieveComponents(ssoId), HttpStatus.OK);
}
}
Here is the Spring boot app class :
#SpringBootApplication
#EnableAutoConfiguration
#EnableJpaRepositories(basePackages="com.ge.power.bis.repositories")
#ComponentScan(basePackages="com.ge.power.bis.managers")
public class Application {
private static Logger logger = Logger.getLogger(Application.class);
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(Application.class);
ApplicationContext ctx = springApplication.run(args);
logger.info("Let's inspect the beans provided by Spring Boot:");
String[] beanNames = ctx.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames)
{
logger.info(beanName);
}
}
}
Here is the structure of my package
When I remove all the annotations in Application.java and just keeping the #SpringBootApplication, It gives the following error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'componentRetrievalController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.ge.power.bis.managers.ComponentRetrievalManager com.ge.power.bis.controllers.ComponentRetrievalController.componentRetrievalManager; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.ge.power.bis.managers.ComponentRetrievalManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapable
#Service was missing on one of the Impl class
You need to mark the service class as "Available to make beans" so the Spring's component-scan will be able to make bean and inject values.
This can be done by #Component annotation. As mentioned in the answer by #sromit, adding #Service annotation will also work, as it already inherits the #Component. #Repository and #Controller also inherit the #Component annotation.

Categories