How to create Custom DataSource in Spring Boot + Spring Data
Solution 1
No need to exclude the built in autoconfiguration.
In you application.yml
myapp:
datasource:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mydb?autoReconnect=true&characterEncoding=utf8
username: myuser
# make sure you exclude password from here
And in your configuration:
// all the other datasource properties will be applied from "myapp.datasource" except password because you excluded it
@ConfigurationProperties(prefix = "myapp.datasource")
@Bean
@Primary // this will override the datasource autoconfiguration and use your own everywhere
public DataSource dataSource() {
String password = retrieveMyPasswordSecurely();
return DataSourceBuilder
.create()
.password(password)
.build();
}
Solution 2
You need to provide an Entity Manager Factory bean. You can follow the convention of creating a bean with the name entityManagerFactory, assuming that you don't already have one. There's a few examples in the Spring documentation here and here.
Assuming you've got a data source, you might be able to get away with as little as this:
@Configuration
public class Database {
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);
LocalContainerEntityManagerFactoryBean factory =
new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("org.yourcompany.jpaentityroot");
factory.setDataSource(dataSource);
return factory;
}
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(emf);
return txManager;
}
@Resource private DataSource dataSource;
}
Related videos on Youtube
Arun Avanathan
Updated on June 04, 2022Comments
-
Arun Avanathan almost 2 years
I want to create Custom DataSource programmatically. This is because I want to fetch password from a secure storage at runtime, instead of hardcoding it in application.yaml.
I have a custom datasource - myapp.datasource.password which has the value of mydb.password.key. Using ApplicationListener I am loading secrets and setting the value of myapp.datasource.password using mydb.password.key as key.
myapp: datasource: driverClassName: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/mydb?autoReconnect=true&characterEncoding=utf8 username: myuser password: mydb.password.key
Now, HibernateJpaAutoConfiguration is trying to connect to DB using mydb.password.key as password and failing at the time of startup.
I tried to exclude DB auto configuration classes
@SpringBootApplication (exclude={ DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class })
But it throws this exception
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available
How to resolve this? Any help is greatly appreciated!
Thanks
-
Arun Avanathan over 6 yearsThanks. This solution fixed the problem!
-
Arun Avanathan over 6 yearsThanks @PaulHicks. We wanted to keep the config, implementation (Hibernate) agnostic. Hence, didn't take this route.