Spring how to set datasource in Spring Boot - java

I'm just learning Spring and I've been struggling for the past couple of days on how to configure the Spring JdbcTemplate to use my PostgreSQL database. I don't know how to do this. I keep reading the documentation, (such as http://docs.spring.io/spring/docs/current/spring-framework-reference/html/jdbc.html) but it seems like I'm going around in circles.
From the errors thrown it seems that it can't instantiate the RelationalDatabase Class that I wrote as a bean. I'm not sure what it would take to instantiate the class properly.
How do I move from something like the guides (Like https://spring.io/guides/gs/relational-data-access/) which totally work to a more complex solution?
Relational Database Class
#Repository
public class RelationalDatabase
{
private JdbcTemplate jdbcTemplate;
public RelationalDatabase(){}
public RelationalDatabase(JdbcTemplate jdbcTemplate)
{
this.jdbcTemplate = jdbcTemplate;
}
#Autowired
public void setDataSource(javax.sql.DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
}
\src\main\resources\application-dev.properties
spring.datasource.url=jdbc:postgresql://192.168.56.102:5432/scibase
spring.datasource.type=org.postgresql.ds.PGPoolingDataSource
spring.datasource.username=lemon
spring.datasource.password=XXXXXX
spring.datasource.platform=postgres
spring.datasource.max-active=100
spring.datasource.name=lime
spring.database.driverClassName=org.postgresql.Drive
Stack Trace (Summary)
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'relationalDatabase': Injection of autowired
dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Could not
autowire method: public void
com.scientifi.papers.db.relational.RelationalDatabase.setDataSource(javax.sql.DataSource);
nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'dataSource' defined in class path resource
[org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$NonEmbeddedConfiguration.class]:
Bean instantiation via factory method failed;
nested exception is
org.springframework.beans.BeanInstantiationException: Failed to
instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw
exception; nested exception is
org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException:
Cannot determine embedded database driver class for database type
NONE. If you want an embedded database please put a supported one on
the classpath. If you have database settings to be loaded from a
particular profile you may need to active it (the profiles "dev "
are currently active).
Thanks!

Did you forget the "r" in Driver? (Cannot determine embedded database driver class for database type NONE)
spring.database.driverClassName=org.postgresql.Driver
instead of
spring.database.driverClassName=org.postgresql.Drive

I Got the same Exception when i was testing my Spring Boot Application from Junit.
I resolved it using the #SpringApplicationConfiguration(classes = Application.class) above the Junit Test class. The Spring Boot application was not getting initialized properly

Related

Spring Boot #Autowire not working. Error creating bean

Hi I have a spring boot project. The main class package is like this :
com.som.demo
I have used an external jar as a maven dependency in my project. In that jar there is a service class annotated with #Service as below :
#Service
public class SomeServiceImpl implements SomeService {
#Autowired
private TreeCacheWrapper ffCoreCache;
#Autowired(required = false)
private ZookeeperProperties zookeeperProperties;
public SomeServiceImpl(TreeCacheWrapper ffCoreCache, ZookeeperProperties zookeeperProperties) {
this.ffCoreCache = ffCoreCache;
this.zookeeperProperties = zookeeperProperties;
}
}
And the main package where this SomeServiceImpl class is as below :
com.som.test
Now in my project when I am autowiring the class I get the bean creation error while running the spring boot app. This is how I am doing :
#Autowired
private SomeService someService;
Error :
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'someServiceImpl'
Unsatisfied dependency expressed through field 'ffCoreCache';
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'ffCoreCache' defined in class path resource [com/som/test/config/ZooKeeperConfig.class]:
Bean instantiation via factory method failed;
nested exception is org.springframework.beans.BeanInstantiationException:
Failed to instantiate [com.som.test.cache.TreeCacheWrapper]:
Factory method 'ffCoreCache' threw exception;
nested exception is java.lang.NoClassDefFoundError: org/apache/curator/retry/ExponentialBackoffRetry
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'ffCoreCache' defined in class path resource [com/som/test/config/ZooKeeperConfig.class]:
Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException:
Failed to instantiate [com.som.test.cache.TreeCacheWrapper]:
Factory method 'ffCoreCache' threw exception; nested exception is java.lang.NoClassDefFoundError: org/apache/curator/retry/ExponentialBackoffRetry
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.som.test.cache.TreeCacheWrapper]:
Factory method 'ffCoreCache' threw exception; nested exception is java.lang.NoClassDefFoundError: org/apache/curator/retry/ExponentialBackoffRetry
Caused by: java.lang.NoClassDefFoundError: org/apache/curator/retry/ExponentialBackoffRetry
Caused by: java.lang.ClassNotFoundException: org.apache.curator.retry.ExponentialBackoffRetry
When spring boot application starts, it scans for beans in the same package as your main class, and all packages beneath it.
Since your main class resides in the package com.som.demo spring boot will find any beans in this package, or in packages like com.som.demo.sample1, com.som.demo.a.b.c etc
However it won't scan com.som.test package because its a "peer" to the main package.
In general you can configure spring boot to scan the packages of your choice with the help of #ComponentScan annotation that accepts a list of base packages to scan. You can put this annotation right on your main class (next to #SpringBootApplication).
However this is kind of against the conventions of spring boot.
Read this tutorial for more technical details and examples.
Annotate Service interface with #Service, not the Implementation class and try to annotate ServiceImplementation class with #Component.
Spring boot by default scan to beans in your main package. you can configure it using
#SpringBootApplication(scanBasePackages={"com.som.demo" , "com.som.test"})

No qualifying bean of type 'java.util.Set<javax.persistence.EntityManager>' Spring Boot 2.0.2

I have a Spring Boot Web application using hibernate that was running just fine on 1.5.7.RELEASE. I decided to upgrade to 2.0.2.
All I had to do to get it compile was change the location of SpringBootServletInitializer. However, when I deploy to my tomcat I get this error:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'jpaContext': Unsatisfied dependency expressed through constructor parameter 0; nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.util.Set<javax.persistence.EntityManager>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
There is NO difference in my properties files or other code. I simply change my spring version in my POM, and I get the error. Here is my connections configuration:
#Configuration
public class ConnectionsConfiguration implements ApplicationListener<ApplicationReadyEvent> {
static final Logger logger = LoggerFactory.getLogger(ConnectionsConfiguration.class);
#Autowired
DataSource dataSource;
#Autowired
private EntityManagerFactory emFactory;
#Bean
#Scope("prototype")
public LocalSessionFactoryBean sessionFactory() throws ClassNotFoundException {
LocalSessionFactoryBean fact = new LocalSessionFactoryBean();
fact.setAnnotatedPackages("com.****.persistence.model");
fact.setPackagesToScan("com.****.persistence.model");
fact.setDataSource(dataSource);
return fact;
}
}
What is the difference between 1.5.7 and 2.0.2 that is creating this error and how do I fix it?
Not sure what the difference is behind the scenes, but the Autowired of the EntityManagerFactory still works, but getting the EntityManager from that factory is no longer default. Adding the bean definition fixes the problem like this:
#Bean
public EntityManager getEntityManager() {
return emFactory.createEntityManager();
}
Relatively simple.

Different Jobrepository datasource per job in spring batch?

If I have 2 jobs, each of which writes to a different datasource, it would make sense to write the spring batch metadata (jobExecution, results, ...) in the datasource which it worked with. However spring batch seems to direct you to have one "primary" datasource to use for that metadata.
I defined two datasources, neither is marked as primary, and the application fails to start:
Field dataSource in org.springframework.batch.core.configuration.annotation.AbstractBatchConfiguration required a single bean, but 2 were found:
- firstDataSource: defined by method 'firstDataSource' in class path resource [secret/DataSourceConfig.class]
- secondDataSource: defined by method 'secondDataSource' in class path resource [secret/DataSourceConfig.class]
Action:
Consider marking one of the beans as #Primary, updating the consumer to accept multiple beans, or using #Qualifier to identify the bean that should be consumed
I tried to create two configurations that each extend DefaultBatchConfigurer:
#Configuration
#EnableBatchProcessing
public class MyJobConfiguration extends DefaultBatchConfigurer {
#Autowired
public JobBuilderFactory jobBuilderFactory;
#Bean
public Job my_job(#Qualifier("somestep") Step step) {
return jobBuilderFactory.get("my_job")
.start(step)
.build();
}
#Bean
#Profile("my_job")
public JobExecution launchMyJob(#Qualifier("my_job") Job job, JobLauncher jobLauncher) throws JobParametersInvalidException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException {
Map<String, JobParameter> params = new HashMap<>();
params.put("Time", new JobParameter(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date())));
return jobLauncher.run(job, new JobParameters(params));
}
#Override
#Autowired
public void setDataSource(#Qualifier("firstDataSource") DataSource dataSource) {
super.setDataSource(dataSource);
}
}
The other one is exactly the same only different job and datasource.
So why does spring still try to create a AbstractBatchConfiguration when clearly I want to do this myself by extending DefaultBatchConfigurer?
More stacktrace:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration': Unsatisfied dependency expressed through field 'dataSource'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'javax.sql.DataSource' available: expected single matching bean but found 2: firstDataSource,secondDataSource
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:587) ~[spring-beans-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:91) ~[spring-beans-5.0.5.RELEASE.jar:5.0.5.RELEASE]
Do you mean using multiple datasource in your project?
Here is a example for you reference
https://github.com/michaelliao/springcloud/tree/master/data-multidatasource
Spring Batch's SimpleBatchConfiguration is brought in via the #EnableBatchProcessing. That uses the BatchConfigurer to provide the components it needs to add to the ApplicationContext. What you really want to do is create a BatchConfigurer that provides the right DataSource at the right time. Then the SimpleBatchConfiguration will use the components created by your configurer to add them to the ApplicationContext.

Failed to instantiate sessionFactory From org.springframework.orm.hibernate5.LocalSessionFactoryBean

We are using spring and hibernate in our application i create LocalSessionFactoryBean object then #autowire SessionFactory in Repository As Follow : Create LocalSessionFactoryBean in AppConfig
#EnableCaching
#EnableAsync
#EnableTransactionManagement
#Configuration
class AppCOnfig extends WebMvcConfigurerAdapter{
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(restDataSource());
sessionFactory.setPackagesToScan("com.xx.yyy");
sessionFactory.setHibernateProperties(hibernateProperties());
sessionFactory.setPhysicalNamingStrategy(new SnakeCaseNamingStrategy());
sessionFactory.setImplicitNamingStrategy(new ImplicitNamingStrategyLegacyHbmImpl());
return sessionFactory;
}
}
In Repository We are Using #autowire annotation as
#Slf4j
#Repository
public class UserRepository {
#Autowired
private SessionFactory sessionFactory;
}
We are using hibernate and spring version as below :
4.3.4.RELEASE
5.2.10.Final
But when i start application i got this error :
Error creating bean with name 'sessionFactory' defined in XXX.AppConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.hibernate5.LocalSessionFactoryBean]: Factory method 'sessionFactory' threw exception; nested exception is java.lang.ArrayStoreException: sun.reflect.annotation.EnumConstantNotPresentExceptionProxy
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1128)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1022)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:512)
I knew there is some issue when spring tried to got session factory from localeSessionFactoryBean But can not figure out how can we solve it.If anyone have some idea about it please help me out.
An EnumConstantNotPresentException is thrown when something tries to reference an enum constant by name when it doesn’t exist. The Proxy variant of it is thrown, in my experience, when there’s reflection involved. If you debug your app with a breaking point on the EnumConstantNotPresentExceptionProxy(Class<? extends Enum<?>>, String) constructor, you should be able to see the class of the enum and the name of the non-existent constant.

Can not apply DaoAuthenticationConfigurer to already built object

I'm getting this exception:
[WARN] org.springframework.web.context.support.GenericWebApplicationContext - Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'accountResource': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private io.ilopezluna.japanathome.service.UserService io.ilopezluna.japanathome.web.rest.AccountResource.userService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.security.crypto.password.PasswordEncoder io.ilopezluna.japanathome.service.UserService.passwordEncoder; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'securityConfiguration': Injection of autowired dependencies failed; nested exception is java.lang.IllegalStateException: Cannot apply org.springframework.security.config.annotation.authentication.configurers.userdetails.DaoAuthenticationConfigurer#54aa5730 to already built object
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:293) ~[spring-beans-4.0.7.RELEASE.jar:4.0.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1186) ~[spring-beans-4.0.7.RELEASE.jar:4.0.7.RELEASE]
You can see more on https://travis-ci.org/ilopezluna/japan-at-home/builds/37866955
This exception is thrown during my execution of tests. But I can't reproduce it on my localhost, I always get a build success :S
It took me two days, but I believe I've finally solved this. In my SecurityConfiguration class I had the following method:
#Configuration
#EnableWebMvcSecurity
#EnableGlobalMethodSecurity(jsr250Enabled=true, prePostEnabled=true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(authenticationService);
}
}
I replaced the configureGlobal method with a configure method:
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(authenticationService);
}
And now everything works fine.
According to this answer the difference is that the using configureGlobal will allow the AuthenticationManager by global method security or another HttpSecurity (WebSecurityConfigurerAdapter).
As you can see above, I am enabling both Web Mvc Security and global method security. According to my unit tests, both continue to work with this change, but there is some debate here at my office on whether this change is correct (ie, if it is configuring global method security correctly), or if there is another problem with this solution.
We believe the root cause of the problem is some type of Spring bug, possibly a race condition. As unlikely as that seems, the problem only manifested itself when we added a empty class to the project, it didn't matter what the class's package or name was.

Categories