Spring JpaConfiguration give an exception on running server - java

I try to configure a JpaConfiguration to working with jetty and H2 (just for a test).
When I run the server I'm receiving an error. But I don't understand the reason.
I'm using spring-data-jpa.
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(basePackages = "my.package.model.repository")
#ComponentScan(basePackages = {"my.package.model.services"})
public class JpaConfiguration {
#Bean
public DataSource dataSource() throws SQLException {
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
return builder.setType(EmbeddedDatabaseType.H2).build();
}
#Bean
public EntityManagerFactory entityManagerFactory() throws SQLException {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("my.package.model.entity");
factory.setDataSource(dataSource());
factory.afterPropertiesSet();
factory.setPersistenceUnitName("test");
return factory.getObject();
}
#Bean
public EntityManager entityManager(EntityManagerFactory entityManagerFactory) {
return entityManagerFactory.createEntityManager();
}
#Bean
public PlatformTransactionManager transactionManager() throws SQLException {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory());
return txManager;
}
#Bean
public HibernateExceptionTranslator hibernateExceptionTranslator() {
return new HibernateExceptionTranslator();
}
}
The error is :
2013-11-29 13:36:33.042:WARN::Nested in org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'memberService': Injection o
f autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private my.package.model.repository.MemberRepository my.package.model.services.MemberServiceImpl.memberRepository; nested exception is org.springframework.beans.f
actory.BeanCreationException: Error creating bean with name 'memberRepository': Cannot create inner bean '(inner bean)' of type [org.springframework.orm.jp
a.SharedEntityManagerCreator] while setting bean property 'entityManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Err
or creating bean with name '(inner bean)#1': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception i
s org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [my/package/config/JpaConfiguration.class]: No matching factory method found: factory bean 'jpaConfiguration'; factory method 'entityManagerFactory()'. Check tha
t a method with the specified name exists and that it is non-static.:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [my/package/config/JpaConfiguration.class]: No matching factory method found: factory bean 'jpaConfiguration'; factory method 'entityManagerFactory()'. Check that
a method with the specified name exists and that it is non-static.
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:536)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.ja
va:1055)
Thanks a lot for your help.

You can do it in a more simple way: you need a single method with LocalContainerEntityManagerFactoryBean as return type. Than, you can inject the EntityManager bean wherever you want without any other fuss.
public class JpaConfiguration {
#Bean
public DataSource dataSource() throws SQLException {
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
return builder.setType(EmbeddedDatabaseType.H2).build();
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws SQLException {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("my.package.model.entity");
factory.setDataSource(dataSource());
factory.afterPropertiesSet();
factory.setPersistenceUnitName("test");
return factory;
}
//remainder configuration for trasnactions and so on
}
#Service
public class Service{
#PersistenceContext(unitName = "test")
private EntityManager em;
}

The problem is coming from my web.xml file.
configuration must content configuration class and not package :
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>my.package.WebConfiguration</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Importatn line is :
<param-value>my.package.WebConfiguration</param-value>
I wrote only
<param-value>my.package</param-value>

Related

Spring JPA – Multiple Databases error Parameter 0 of constructor in '' required a bean of type '' that could not be found

I try to implement Multiple Databases on MySql and Sql server2019 so i folow this this documentation spring-data-jpa-multiple-databases
but i have error in the second dataBase
Parameter 0 of constructor in com.hexa.infrastructure.doa.SecondAdapter required a bean of type 'com.hexa.infrastructure.doa.ISecondRepositoryJpa' that could not be found.
#NoArgsConstructor
#Configuration
#EnableJpaRepositories(
basePackages = "com.hexa.infrastructure.doa.Second",
entityManagerFactoryRef = "secondEntityManager",
transactionManagerRef = "secondTransactionManager")
public class PersistencesecondAutoConfiguration {
#Autowired
private Environment env;
#Bean
#ConfigurationProperties(prefix="spring.datasource-mysql")
public DataSource secondDataSource() {
return DataSourceBuilder.create().build();
}
#Bean
public LocalContainerEntityManagerFactoryBean secondEntityManager() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(secondDataSource());
em.setPackagesToScan("com.hexa.infrastructure.jpa.entities.sqlserver.SecondEntity");
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
final HashMap<String, Object> properties = new HashMap<String, Object>();
properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
em.setJpaPropertyMap(properties);
return em;
}
#Bean
public PlatformTransactionManager secondTransactionManager() {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(secondEntityManager().getObject());
return transactionManager;
}
}
#Configuration
#EnableJpaRepositories(
basePackages = "com.hexa.infrastructure.doa.FirstAdapter",
entityManagerFactoryRef = "firstEntityManager",
transactionManagerRef = "firstTransactionManager"
)
public class PersistenceFirsyConfiguration {
#Autowired
private Environment env;
#Primary
#Bean
#ConfigurationProperties(prefix="spring.datasource")
public DataSource firstDataSource() {
return DataSourceBuilder.create().build();
}
#Primary
#Bean
public LocalContainerEntityManagerFactoryBean firstEntityManager() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(firstDataSource());
em.setPackagesToScan("com.hexa.infrastructure.jpa.entities.mysql");
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
final HashMap<String, Object> properties = new HashMap<String, Object>();
properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
em.setJpaPropertyMap(properties);
return em;
}
#Primary
#Bean
public PlatformTransactionManager firstTransactionManager() {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(firstEntityManager().getObject());
return transactionManager;
}
}
I don't understand why it can't find the bean
I have test on a single Entity and on the package my same error.
I also changed invercy the primary annotation same result
if i change to basePackages = "com.hexa.infrastructure.doa"
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'secondEndPoint' defined in file [\\\com\hexa\application\SecondEndPoint.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'secondService' defined in file [\\\com\hexa\domain\SecondService.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'secondAdapter' defined in file [\\\com\hexa\infrastructure\doa\SecondAdapter.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ISecondRepositoryJpa' defined in com.hexa.infrastructure.doa.ISecondRepositoryJpa defined in #EnableJpaRepositories declared on PersistenceSecondAutoConfiguration: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class com.hexa.infrastructure.jpa.entities.sqlserver.SecondEntity
now it work but when i call api now i have sql error,
First dabase With data
java.sql.SQLSyntaxErrorException: (conn=457) Unknown column 'firstent0_.dateCreation' in 'field list'
new base Second
com.microsoft.sqlserver.jdbc.SQLServerException: Invalid object name 'entity2'.
Your basepackage in #EnableJpaRepositories
#EnableJpaRepositories(
basePackages = "com.hexa.infrastructure.doa.Second"
Means it won't find your Repository class which is is in package
com.hexa.infrastructure.doa.ISecondRepositoryJpa

Spring boot / Spring security with dedicated database for security

I am looking desesperatly for spring boot running with spring security configured with two different databases. One for application's data and the other one for spring security only.
I have worked with https://www.baeldung.com/spring-data-jpa-multiple-databases for multiple databases configurations.With that too https://www.laulem.com/dev/spring-boot/spring-security.html for spring security.
But after several work, I'am unable to have a working project with spring boot and spring security with two separates database.
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
#PropertySource({"classpath:application.properties"})
#EnableJpaRepositories(
basePackages = "com.myApp.security.repositories",
entityManagerFactoryRef = "productEntityManager",
transactionManagerRef = "productTransactionManager"
)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private Environment env;
#Autowired
#Qualifier("userDetailsService")
private UserDetailsService customUserDetailsService;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests().antMatchers("/").permitAll()
.anyRequest().authenticated()
.and().formLogin().loginPage("/login").successHandler( myAuthenticationSuccessHandler() ).failureUrl("/login?error=true").permitAll()
.and().logout().deleteCookies("JSESSIONID").logoutUrl("/logout").logoutSuccessUrl("/login");
}
#Override
protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception {
authManagerBuilder.userDetailsService(customUserDetailsService).passwordEncoder(myAppPasswordEncoder());
}
/**
* Cryptage des mots de passe
*
* #return
*/
#Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
/**
* No password encryption (dev only!!!)
*
* #return
*/
#Bean
public myAppPasswordEncoder myAppPasswordEncoder() {
return new myAppPasswordEncoder();
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public AuthenticationSuccessHandler myAuthenticationSuccessHandler(){
return new myAppUrlAuthenticationSuccessHandler();
}
#Bean
#ConfigurationProperties(prefix="spring.productdb-datasource")
public DataSource productDataSource() {
return DataSourceBuilder.create().build();
}
#Bean
public LocalContainerEntityManagerFactoryBean productEntityManager() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(productDataSource());
em.setPackagesToScan("com.myApp.security.metier.impl");
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
final HashMap<String, Object> properties = new HashMap<String, Object>();
properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
em.setJpaPropertyMap(properties);
return em;
}
#Bean
public PlatformTransactionManager productTransactionManager() {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(productEntityManager().getObject());
return transactionManager;
}
}
I get this kind of errors
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'securityConfig':
Unsatisfied dependency expressed through field 'customUserDetailsService';
nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'userDetailsService':
Unsatisfied dependency expressed through field 'userService';
nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'userService':
Unsatisfied dependency expressed through field 'userRepository';
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'userRepository' defined in com.myApp.security.repositories.UserRepository defined in #EnableJpaRepositories declared on SecurityConfig:
Cannot create inner bean '(inner bean)#2239ae10' 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)#2239ae10':
Cannot resolve reference to bean 'productEntityManager' while setting constructor argument;
nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'productEntityManager': Requested bean is currently in creation:
Is there an unresolvable circular reference?
Edit:
The problem seems to be caused by WebSecurityConfigurerAdapter inheritance. Some beans are instanciated by this class and create conflict with the dedicated datasource I try to configure for the "security" part of my spring-boot app.
I'm still searching...
Edit 2:
If anyboby's got a git URL to a working sample example...

Circular reference involving containing bean 'XXX' - consider declaring the factory method as static for independence from its containing instance

I am creating two projects globalDB and GlobalWeb using spring. I want to create multiple database connections in GlobalWeb, Jdbc properties are fetched from GlobalDB project dao layer at the time of GlobalWeb initiation. When i run the global web, Am getting the following exception.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'globalWebConfig': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.kla.it.dao.Dao com.kla.it.global.conf.GlobalWebConfig.dao; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'daoImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.springframework.jdbc.core.JdbcTemplate com.kla.it.dao.impl.DaoImpl.template; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'template' defined in class path resource [com/kla/it/database/DatabaseConfig.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [javax.sql.DataSource]: : Error creating bean with name 'partsDs' defined in com.kla.it.global.conf.GlobalWebConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.jdbc.datasource.DriverManagerDataSource]: Circular reference involving containing bean 'globalWebConfig' - consider declaring the factory method as static for independence from its containing instance. Factory method 'getPartsDataSource' threw exception; nested exception is java.lang.NullPointerException; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'partsDs' defined in com.kla.it.global.conf.GlobalWebConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.jdbc.datasource.DriverManagerDataSource]: Circular reference involving containing bean 'globalWebConfig' - consider declaring the factory method as static for independence from its containing instance. Factory method 'getPartsDataSource' threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:305)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:834)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:446)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:328)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4680)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5143)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:717)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:690)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:705)
GlobalDB configuration class
#Configuration
#ComponentScan(basePackages = "com.kla.it")
#PropertySource(value = {"classpath:database.properties"})
public class DatabaseConfig {
#Autowired
private Environment env;
// #Bean(name="ds")
public DataSource getDataSource(){
System.out.println("++++++++++++++++DATABASE++++++++++++++START++++++++++++");
System.out.println("Method to crate data source");
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("net.snowflake.client.jdbc.SnowflakeDriver");
ds.setUrl(env.getRequiredProperty("db.url"));
ds.setUsername(env.getRequiredProperty( "db.username"));
ds.setPassword(env.getRequiredProperty( "db.password"));
return ds;
}
#Bean(name="template")
public JdbcTemplate jdbcTemplate(DataSource ds) {
System.out.println("Jdbc template method called.");
JdbcTemplate template = new JdbcTemplate(ds);
template.setResultsMapCaseInsensitive(true);
System.out.println("++++++++++++++++DATABASE++++++++++++++END+++++++++++");
return template;
}
}
GlobalDB Dao Layer class
#Repository
#Qualifier("dao")
public class DaoImpl implements Dao{
#Autowired
JdbcTemplate template;
#Override
public Map<String, String> getConnectionsData(String appName, String env) {
List<Map<String, Object>> reportsList = new ArrayList<>();
Map<String, String> dataSourceMap = new HashMap<>();
String qry = "SELECT * FROM DB_CONFIG WHERE name = '"+appName+"' AND ev = '"+env+"'";
reportsList = template.queryForList(qry);
int count = 1;
for (Map<String, Object> map : reportsList) {
dataSourceMap.put(String.valueOf(map.get("prop")), String.valueOf(map.get("val")));
}
return dataSourceMap;
}
}
GlobalWeb Config class
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.kla.it")
#PropertySource(value = {"classpath:global.properties"})
public class GlobalWebConfig extends WebMvcConfigurerAdapter {
#Autowired(required=true)
Dao dao;
#Bean(name = "partsDs")
public DriverManagerDataSource getPartsDataSource(){
Map<String, String> dsMap = dao.getConnectionsData("parts", "dev");
DriverManagerDataSource partsDs= new DriverManagerDataSource();
partsDs.setDriverClassName(dsMap.get("driver"));
partsDs.setUrl(dsMap.get("url"));
partsDs.setUsername(dsMap.get("user"));
partsDs.setPassword(dsMap.get("password"));
return partsDs;
}
#Bean(name = "cosmosDs")
public DriverManagerDataSource getCosmosDataSource(){
Map<String, String> dsMap = dao.getConnectionsData("cosmos", "dev");
DriverManagerDataSource cosmosDs = new DriverManagerDataSource();
cosmosDs.setDriverClassName(dsMap.get("driver"));
cosmosDs.setUrl(dsMap.get("url"));
cosmosDs.setUsername(dsMap.get("user"));
cosmosDs.setPassword(dsMap.get("password"));
return cosmosDs;
}
#Bean(name = "itsDs")
public DataSource getITSDataSource(){
Map<String, String> dsMap = dao.getConnectionsData("ITSecurity", "dev");
DriverManagerDataSource itsDs= new DriverManagerDataSource();
itsDs.setDriverClassName(dsMap.get("driver"));
itsDs.setUrl(dsMap.get("url"));
itsDs.setUsername(dsMap.get("user"));
itsDs.setPassword(dsMap.get("password"));
return itsDs;
}
#Bean(name = "sfPartsDB")
public JdbcTemplate snowFlakeParts() {
System.out.println("Jdbc template method called.");
DataSource cosmosDs = getPartsDataSource();
JdbcTemplate sfPartsDB = new JdbcTemplate(cosmosDs);
sfPartsDB.setResultsMapCaseInsensitive(true);
return sfPartsDB;
}
#Bean(name = "sfCosmosDB")
public JdbcTemplate snowFlakeCosmos() {
System.out.println("Jdbc template method called.");
DataSource cosmosDs = getCosmosDataSource();
JdbcTemplate sfCosmosDB = new JdbcTemplate(cosmosDs);
sfCosmosDB.setResultsMapCaseInsensitive(true);
return sfCosmosDB;
}
//
#Bean(name = "oracleDB")
public JdbcTemplate oracleTemplate() {
DataSource itsDs = getITSDataSource();
JdbcTemplate oracleDB = new JdbcTemplate(itsDs);
oracleDB.setResultsMapCaseInsensitive(true);
return oracleDB;
}
}
Please try with below code. It works!!
1. #Qualifier to particular datasource reference(by name).
2. #Import Aggregate all the configuration classes.
#Configuration
#ComponentScan(basePackages = "com.kla.it")
#PropertySource(value = {"classpath:database.properties"})
public class DatabaseConfig {
#Autowired
private Environment env;
#Bean(name="ds")
public DataSource getDataSource(){
System.out.println("++++++++++++++++DATABASE++++++++++++++START++++++++++++");
System.out.println("Method to crate data source");
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("net.snowflake.client.jdbc.SnowflakeDriver");
ds.setUrl(env.getRequiredProperty("db.url"));
ds.setUsername(env.getRequiredProperty( "db.username"));
ds.setPassword(env.getRequiredProperty( "db.password"));
return ds;
}
#Bean(name="template")
public JdbcTemplate jdbcTemplate(#Qualifier("ds")DataSource ds) {
System.out.println("Jdbc template method called.");
JdbcTemplate template = new JdbcTemplate(ds);
template.setResultsMapCaseInsensitive(true);
System.out.println("++++++++++++++++DATABASE++++++++++++++END+++++++++++");
return template;
}
}
#Import(DatabaseConfig.class) /* add this line to aggrgate java configuration classes*/
#Configuration
#EnableWebMvc
#ComponentScanenter code here(basePackages = "com.kla.it")
#PropertySource(value = {"classpath:global.properties"})
public class GlobalWebConfig extends WebMvcConfigurerAdapter {
}

Can't Autowire SessionFactory with Java Configuration

The configuration class name is marked in yellow color and it says Application context not configured for this file
My Config Class :
#Configuration
#EnableTransactionManagement
public class DatabaseConfig {
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan("com.tornikeshelia.model");
sessionFactory.setHibernateProperties(getHibernateProperties());
return sessionFactory;
}
private Properties getHibernateProperties(){
Properties prop = new Properties();
Properties properties = new Properties();
properties.setProperty("hibernate.hbm2ddl.auto", "update");
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL57InnoDBDialect");
return properties;
}
#Bean(name = "dataSource")
public BasicDataSource dataSource(){
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/test?allowPublicKeyRetrieval=true&useSSL=false&useUnicode=true&characterEncoding=utf-8");
ds.setUsername("username");
//ds.setPassword("");
return ds;
}
#Bean
#Autowired
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory){
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(sessionFactory);
return txManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
return new PersistenceExceptionTranslationPostProcessor();
}
}
I've commented out ds.setPassword because my test database doesn't have any password protection. Also the hibernate doesn't auto create tables from my Entity class , I think thats because of this configuration file not being read by Spring
When trying to autowire SessionFactor in my DaoImpl class via :
#Resource(name = "sessionFactory")
private SessionFactory session;
The error says Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personDaoImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.hibernate.SessionFactory com.tornikeshelia.dao.PersonDaoImpl.sessionFactory; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.hibernate.SessionFactory] 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)}
SOLUTION :
The problem was 1)The location of config package and 2) in the warning message that was on the class name (yellowed out with message - Application context not configured for this file
So if anybody has same problem here's the solution -
1) move your config package inside the parent package where the model package is
2) Step on the class name (click anywhere on the class name) the yellow light bulb will appear, click on it and then click on configure application context, a new tab will appear where you should choose this class and press okay.
Try to edit your config class and update the transationManager() bean :
#Bean
public HibernateTransactionManager transactionManager(){
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(sessionFactory().getObject());
return txManager;
}
Your error may occur because you try to inject a bean that has not bean created yet.

Adding beans breaks Spring Configuration

EDIT 1:
I'm currently calling this from a Main class like so:
public class Main
{
public static void main(String[] args)
{
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringAppConfig.class);
DataSource dSource = ctx.getBean(DataSource.class);
System.out.println(dSource.getClass().toString());
if (dSource instanceof Log4jdbcProxyDataSource)
{
Log4jdbcProxyDataSource log4jdbcProxyDataSource = (Log4jdbcProxyDataSource) dSource;
Object lf = log4jdbcProxyDataSource.getLogFormatter();
System.out.println(lf.getClass().toString());
}
System.exit(0);
}
}
Original:
Code follows after explanation:
I have a Spring application with a JavaConfig, call it the primary app, that imports another Spring JavaConfig class from a library. This imported JavaConfig is supposed to wrap any DataSource created in the primary app with an Aspect, which has an autowired LogDelegator.
As long as the primary app contains only a DataSource, everything works. But as soon as I add an EntityManager to the primary app, I get a nested IllegalArgumentException saying that the LogDelegator is null.
Primary App's Config:
#Configuration
#Import(MonitoringConfig.class)
public class SpringAppConfig
{
#Bean
public DataSource dataSource()
{
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
EmbeddedDatabase db = builder.setType(EmbeddedDatabaseType.H2).build();
return db;
}
}
Imported Library Config:
#Configuration
#EnableSpringConfigured
public class MonitoringConfig extends WebMvcConfigurerAdapter
{
#Bean
public LogDelegator logDelegator()
{
return new LogDelegator();
}
#Bean
public ConfigurationAspect configurationAspect()
{
return Aspects.aspectOf(ConfigurationAspect.class);
}
}
The Aspect:
#Configurable
public aspect ConfigurationAspect
{
#Autowired
LogDelegator logDelegator;
Object around() : execution(public DataSource (#Configuration *).*(..)) {
Object ret = proceed();
if (ret instanceof DataSource) {
Log4jdbcProxyDataSource dataSource = new Log4jdbcProxyDataSource((DataSource) ret);
dataSource.setLogFormatter(logDelegator);
return dataSource;
} else {
return ret;
}
}
This code works great until I add the following,
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory()
{
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);
vendorAdapter.setDatabase(Database.H2);
vendorAdapter.setShowSql(true);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setDataSource(dataSource());
factory.setJpaVendorAdapter(vendorAdapter);
return factory;
}
#Bean
public EntityManager entityManager()
{
return entityManagerFactory().getObject().createEntityManager();
}
#Bean
public PlatformTransactionManager transactionManager()
{
JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
jpaTransactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return jpaTransactionManager;
}
and then I get:
java.lang.reflect.InvocationTargetException at java.lang.Thread.run(Thread.java:722)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class SpringAppConfig: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [publ
ic org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean com.fl.sas.configurable.config.SpringAppConfig.entityManagerFactory()] threw exception; ne
sted exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class SpringAppConfig: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public
javax.sql.DataSource SpringAppConfig.dataSource()] threw exception; nested exception is java.lang.IllegalArgumentException: log4j
dbc: logDelegator cannot be null.
Can anyone help?
I needed to add
#Depends(value="configurationAspect") on dataSource()
Luca Basso Ricci answered the question. If he ever adds the answer, I'll give him the credit. :)

Categories

Resources