I have a problem with Spring Boot 2.0.0. When I throw an RuntimeException it is not rollback the transaction. I was using Spring Boot 1.5.9 with the same settings and it worked. It just migrated to Spring Boot 2 and stopped working.
My Configuration class:
#Configuration
#EnableJpaRepositories(basePackages = "com.test.repository")
#EnableTransactionManagement
public class DatabaseConfiguration {
public static final String MODEL_PACKAGE = "com.test.model";
#Value("${jdbc.url}")
private String url;
#Value("${jdbc.username}")
private String username;
#Value("${jdbc.password}")
private String password;
#Bean
public DataSource dataSource() throws SQLException {
org.apache.tomcat.jdbc.pool.DataSource dataSource = new org.apache.tomcat.jdbc.pool.DataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl(this.url);
dataSource.setUsername(this.username);
dataSource.setPassword(this.password);
return dataSource;
}
#Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
My Business class:
#Service
public class TestBusinessImpl implements TestBusiness {
#Override
#Transactional
public void save(final Test test) {
this.testRepository.save(test);
throw new RuntimeException("Test rollback");
}
}
Does anyone know what may be happening?
Which dialect are you using? You must be specifying spring.jpa.properties.hibernate.dialect
Springboot 2.0 #Transaction doesn't get supported by org.hibernate.dialect.MySQL5Dialect
Rather use org.hibernate.dialect.MySQL5InnoDBDialect
Related
I am facing some issues while writing integration tests for Spring Batch jobs. The main problem is that an exception is thrown whenever a transaction is started inside the batch job.
Well, first things first. Imagine this is the step of a simple job. A Tasklet for the sake of simplicity. Of course, it is used in a proper batch config (MyBatchConfig) which I also omit for brevity.
#Component
public class SimpleTask implements Tasklet {
private final MyRepository myRepository;
public SimpleTask(MyRepository myRepository) {
this.myRepository = myRepository;
}
#Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
myRepository.deleteAll(); // or maybe saveAll() or some other #Transactional method
return RepeatStatus.FINISHED;
}
}
MyRepository is a very unspecial CrudRepository.
Now, to test that job I use the following test class.
#SpringBatchTest
#EnableAutoConfiguration
#SpringJUnitConfig(classes = {
H2DataSourceConfig.class, // <-- this is a configuration bean for an in-memory testing database
MyBatchConfig.class
})
public class MyBatchJobTest {
#Autowired
private JobLauncherTestUtils jobLauncherTestUtils;
#Autowired
private JobRepositoryTestUtils jobRepositoryTestUtils;
#Autowired
private MyRepository myRepository;
#Test
public void testJob() throws Exception {
var testItems = List.of(
new MyTestItem(1),
new MyTestItem(2),
new MyTestItem(3)
);
myRepository.saveAll(testItems); // <--- works perfectly well
jobLauncherTestUtils.launchJob();
}
}
When it comes to the tasklet execution and more precisely to the deleteAll() method call this exception is fired:
org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is java.lang.IllegalStateException: Already value [org.springframework.jdbc.datasource.ConnectionHolder#68f48807] for key [org.springframework.jdbc.datasource.DriverManagerDataSource#49a6f486] bound to thread [SimpleAsyncTaskExecutor-1]
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:448)
...
Do you have any ideas why this is happening?
As a workaround I currently mock the repository with #MockBean and back it with an ArrayList but this is not what the inventor intended, I guess.
Any advice?
Kind regards
Update 1.1 (includes solution)
The mentioned data source configuration class is
#Configuration
#EnableJpaRepositories(
basePackages = {"my.project.persistence.repository"},
entityManagerFactoryRef = "myTestEntityManagerFactory",
transactionManagerRef = "myTestTransactionManager"
)
#EnableTransactionManagement
public class H2DataSourceConfig {
#Bean
public DataSource myTestDataSource() {
var dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.h2.Driver");
dataSource.setUrl("jdbc:h2:mem:myDb;DB_CLOSE_DELAY=-1");
return dataSource;
}
#Bean
public LocalContainerEntityManagerFactoryBean myTestEntityManagerFactory() {
var emFactory = new LocalContainerEntityManagerFactoryBean();
var adapter = new HibernateJpaVendorAdapter();
adapter.setDatabasePlatform("org.hibernate.dialect.H2Dialect");
adapter.setGenerateDdl(true);
emFactory.setDataSource(myTestDataSource());
emFactory.setPackagesToScan("my.project.persistence.model");
emFactory.setJpaVendorAdapter(adapter);
return emFactory;
}
#Bean
public PlatformTransactionManager myTestTransactionManager() {
return new JpaTransactionManager(myTestEntityManagerFactory().getObject());
}
#Bean
public BatchConfigurer testBatchConfigurer() {
return new DefaultBatchConfigurer() {
#Override
public PlatformTransactionManager getTransactionManager() {
return myTestTransactionManager();
}
};
}
}
By default, when you declare a datasource in your application context, Spring Batch will use a DataSourceTransactionManager to drive step transactions, but this transaction manager knows nothing about your JPA context.
If you want to use another transaction manager, you need to override BatchConfigurer#getTransactionManager and return the transaction manager you want to use to drive step transactions. In your case, you are only declaring a transaction manager bean in the application context which is not enough. Here a quick example:
#Bean
public BatchConfigurer batchConfigurer() {
return new DefaultBatchConfigurer() {
#Override
public PlatformTransactionManager getTransactionManager() {
return new JpaTransactionManager(myTestEntityManagerFactory().getObject());
}
};
}
For more details, please refer to the reference documentation.
I have a spring batch project wherein I read data from a datasource , process the data and write into another primary data source. I am extending CrudRepository for dao operations.
I am trying to configure multiple datasources for my springbatch + spring boot application below is the package structure :
myproject
---com
---batch
---config
---firstDsConfig.java
---secondDsConfig.java
---firstrepository
---firstCrudRepository.java
---secondRepository
---SecondCrudRepository.java
---firstEntity
---firstDBEntity.java
---secondEntity
---secondDBEntity.java
----main
---MyMainClass.java
Code for firstDsConfig.java:
#Configuration
#EnableJpaRepositories(
entityManagerFactoryRef = "firstEntityManagerFactory",
transactionManagerRef = "firstTransactionManager",
basePackages = "com.batch.firstrepository"
)
#EnableTransactionManagement
public class FirstDbConfig {
#Primary
#Bean(name = "firstEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean firstEntityManagerFactory(final EntityManagerFactoryBuilder builder,
final #Qualifier("firstDs") DataSource dataSource) {
return builder
.dataSource(dataSource)
.packages("com.batch.firstEntity")
.persistenceUnit("abc")
.build();
}
#Primary
#Bean(name = "firstTransactionManager")
public PlatformTransactionManager firstTransactionManager(#Qualifier("firstEntityManagerFactory")
EntityManagerFactory firstEntityManagerFactory) {
return new JpaTransactionManager(firstEntityManagerFactory);
}
#Primary
#Bean(name = "firstDs")
#ConfigurationProperties(prefix = "spring.datasource.first")
public DataSource firstDataSource() {
return DataSourceBuilder.create().build();
}
}
Code for secondDsConfig:
#Configuration
#EnableJpaRepositories(
entityManagerFactoryRef = "secondEntityManagerFactory",
transactionManagerRef = "secondTransactionManager",
basePackages = "com.batch.secondrepository"
)
#EnableTransactionManagement
public class FirstDbConfig {
#Primary
#Bean(name = "secondEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean secondEntityManagerFactory(final EntityManagerFactoryBuilder builder,
final #Qualifier("secondDs") DataSource dataSource) {
return builder
.dataSource(dataSource)
.packages("com.batch.secondEntity")
.persistenceUnit("xyz")
.build();
}
#Primary
#Bean(name = "secondTransactionManager")
public PlatformTransactionManager secondTransactionManager(#Qualifier("secondEntityManagerFactory")
EntityManagerFactory firstEntityManagerFactory) {
return new JpaTransactionManager(secondEntityManagerFactory);
}
#Primary
#Bean(name = "secondDs")
#ConfigurationProperties(prefix = "spring.datasource.second")
public DataSource secondDataSource() {
return DataSourceBuilder.create().build();
}
}
Here is my main class
#EnableScheduling
#EnableBatchProcessing
#SpringBootApplication(scanBasePackages = { "com.batch" })
public class MyMainClass {
#Autowired
private JobLauncher jobLauncher;
#Autowired
private JobRepository jobRepository;
#Autowired
#Qualifier(firstDs)
private DataSource dataSource;
#Autowired
#Qualifier("myJob")
private Job job;
public static void main(String[] args) throws Exception {
SpringApplication.run(MyMainClass.class, args);
}
#EventListener(ApplicationReadyEvent.class)
private void start() throws Exception {
jobLauncher.run(job, new JobParameters());
}
#Bean(name="jobService")
public JobService jobService() throws Exception {
SimpleJobServiceFactoryBean factoryBean = new SimpleJobServiceFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setJobRepository(jobRepository);
factoryBean.setJobLocator(new MapJobRegistry());
factoryBean.setJobLauncher(jobLauncher);
factoryBean.afterPropertiesSet();
return factoryBean.getObject();
}
}
Here are the crud repo:
First curd repo
public interface FirstCrudRepository extends CrudRepository<FirstDbEntity, Integer> {
List<FirstDbEntity> findByOId(String oId);
}
Second curd repo
public interface SecondCrudRepository extends CrudRepository<SecondDbEntity, Integer> {
List<SecondDbEntity> findByPid(String pid);
}
When I run my application I see following error while saving record using FirstCrudRepository:
org.springframework.transaction.IllegalTransactionStateException: Pre-bound JDBC Connection found! JpaTransactionManager does not support running within DataSourceTransactionManager if told to manage the DataSource itself. It is recommended to use a single JpaTransactionManager for all transactions on a single DataSource, no matter whether JPA or JDBC access.
Note: I am able to fetch details successfully from SecondCrudRepository
By default, if you provide a DataSource, Spring Batch will use a DataSourceTransactionManager which knows nothing about your JPA configuration. You need to tell Spring Batch to use your JpaTransactionManager. This is explained in the:
reference documentation: https://docs.spring.io/spring-batch/4.1.x/reference/html/index-single.html#javaConfig.
Javadoc of #EnableBatchProcessing: https://docs.spring.io/spring-batch/4.1.x/api/org/springframework/batch/core/configuration/annotation/EnableBatchProcessing.html
I suspect there are 2 different transaction managers present which would be causing issue. Annotate with #Transactional and specifying the transaction manager would help
Source:
Spring - Is it possible to use multiple transaction managers in the same application?
I tried setting up using Jooq with Spring JDBC, everything is working properly except transactions.
This is my current setup:
#Configuration
public class DALConfig {
#Value("${jdbcUrl}")
String jdbcUrl;
#Value("${username}")
String username;
#Value("${password}")
String password;
#Bean(destroyMethod = "close")
DataSource getDataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setUrl(jdbcUrl);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
return dataSource;
}
#Bean(name="transactionManager")
DataSourceTransactionManager getDataSourceTransactionManager() {
return new DataSourceTransactionManager(getDataSource());
}
#Bean(name="transactionAwareDataSource")
TransactionAwareDataSourceProxy getTransactionAwareDataSourceProxy() {
return new TransactionAwareDataSourceProxy(getDataSource());
}
#Bean(name="connectionProvider")
DataSourceConnectionProvider getDataSourceConnectionProvider() {
return new DataSourceConnectionProvider(getTransactionAwareDataSourceProxy());
}
#Bean
DefaultDSLContext getDefaultDSLContext() {
return new DefaultDSLContext(getConfiguration());
}
#Bean
DefaultConfiguration getConfiguration() {
DefaultConfiguration config = new DefaultConfiguration();
config.set(SQLDialect.MYSQL);
config.setConnectionProvider(getDataSourceConnectionProvider());
return config;
}
#Bean
CourseDao getCourseDao() {
return new CourseDao(getConfiguration());
}
}
I am using #Transactional(propagation = Propagation.MANDATORY) annotation on the method which inserts a new Course, but I am getting the following exception org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation 'mandatory'.
I have read the docs for spring and jooq but I have not been able to figure out what is missing and what to do to resolve this. Can someone point out what am I missing here.
OK, I got the problem the exception which was supposed to rollback the transaction was happening outside the scope of the transaction. If I added #Transactional in the scope which includes the exception, the rollback works properly.
Also the propagation should be Propagation.MANDATORY should be changed to Propagation.REQUIRED (which is the default).
I am working on spring boot multi tenancy application. I have configured multi datasources as shown below :
application.properties
spring.multitenancy.datasource1.url=jdbc:mysql://localhost:3306/db1
spring.multitenancy.datasource1.username=root
spring.multitenancy.datasource1.password=****
spring.multitenancy.datasource1.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.multitenancy.datasource2.url=jdbc:mysql://localhost:3306/db2
spring.multitenancy.datasource2.username=root
spring.multitenancy.datasource2.password=****
spring.multitenancy.datasource2.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.multitenancy.datasource3.url=jdbc:mysql://localhost:3306/db3
spring.multitenancy.datasource3.username=root
spring.multitenancy.datasource3.password=****
spring.multitenancy.datasource3.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
DataSourceBasedMultiTenantConnectionProviderImpl.java
#Component
public class DataSourceBasedMultiTenantConnectionProviderImpl extends AbstractDataSourceBasedMultiTenantConnectionProviderImpl {
private static final long serialVersionUID = 8168907057647334460L;
private static final String DEFAULT_TENANT_ID = "tenant_1";
#Autowired
private DataSource dataSource1;
#Autowired
private DataSource dataSource2;
#Autowired
private DataSource dataSource3;
private Map<String, DataSource> map;
#PostConstruct
public void load() {
map = new HashMap<>();
map.put("tenant_1", dataSource1);
map.put("tenant_2", dataSource2);
map.put("tenant_3", dataSource3);
}
#Override
protected DataSource selectAnyDataSource() {
return map.get(DEFAULT_TENANT_ID);
}
#Override
protected DataSource selectDataSource(String tenantIdentifier) {
return map.get(tenantIdentifier);
}
}
MultitenancyProperties.java
#ConfigurationProperties("spring.multitenancy")
public class MultitenancyProperties {
#NestedConfigurationProperty
private DataSourceProperties datasource1;
#NestedConfigurationProperty
private DataSourceProperties datasource2;
#NestedConfigurationProperty
private DataSourceProperties datasource3;
public DataSourceProperties getDatasource1() {
return datasource1;
}
public void setDatasource1(DataSourceProperties datasource1) {
this.datasource1 = datasource1;
}
public DataSourceProperties getDatasource2() {
return datasource2;
}
public void setDatasource2(DataSourceProperties datasource2) {
this.datasource2 = datasource2;
}
public DataSourceProperties getDatasource3() {
return datasource3;
}
public void setDatasource3(DataSourceProperties datasource3) {
this.datasource3 = datasource3;
}
}
MultiTenancyJpaConfiguration.java
#Configuration
#EnableConfigurationProperties(JpaProperties.class)
public class MultiTenancyJpaConfiguration {
#Autowired
private DataSource dataSource;
#Autowired
private JpaProperties jpaProperties;
#Autowired
private MultiTenantConnectionProvider multiTenantConnectionProvider;
#Autowired
private CurrentTenantIdentifierResolver currentTenantIdentifierResolver;
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder) {
Map<String, Object> hibernateProps = new LinkedHashMap<>();
hibernateProps.putAll(jpaProperties.getHibernateProperties(dataSource));
hibernateProps.put(Environment.MULTI_TENANT, MultiTenancyStrategy.DATABASE);
hibernateProps.put(Environment.MULTI_TENANT_CONNECTION_PROVIDER, multiTenantConnectionProvider);
hibernateProps.put(Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, currentTenantIdentifierResolver);
hibernateProps.put(Environment.DIALECT, "org.hibernate.dialect.MySQLDialect");
return builder.dataSource(dataSource).packages(HotelEntity.class.getPackage().getName()).properties(hibernateProps).jta(false).build();
}
}
Application launcher
#SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
#EnableConfigurationProperties(MultitenancyProperties.class)
public class Application {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
}
}
When I run the boot application, all tables are created in only first data source.
1) How can I create tables in all data sources on application startup?
2) How to see connections opened/closed for each of the data sources?
3) Is there a better way of configuring multi tenancy application using spring boot for better performance?
As #Alex said, you need differnt EntityManagers, TransactionManager and Datasources. Here is how I would do it
#Configuration
#EnableJpaRepositories(
entityManagerFactoryRef = "dataSource1EntityManagerFactory",
transactionManagerRef = "dataSource1TransactionManager",
basePackageClasses = dataSource1Repository.class)
public class DataSource1Config extends SqlConfig{// Put all common code in base class SqlConfig. If not remove it
#Bean
#Primary
public DataSource dataSource1() {
//create dataSource using MultitenancyProperties::getDataSource1
}
#Primary
#Bean(name = "dataSource1TransactionManager")
PlatformTransactionManager dataSource1TransactionManager(EntityManagerFactory dataSource1EntityManagerFactory) {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(dataSource1EntityManagerFactory);
return txManager;
}
#Primary
#Bean(name = "dataSource1EntityManagerFactory")
LocalContainerEntityManagerFactoryBean dataSource1EntityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource1());
em.setPackagesToScan(dataSource1Repository.class.getPackage().getName(), dataSource1ModelClass.class.getPackage().getName());
em.setPersistenceUnitName("dataSource1Db");
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(false);
em.setJpaVendorAdapter(vendorAdapter);
return em;
}
}
You can create two other classes like this. Remember to use #Primary on only one instace of datasource, transactionmanger and entitymanager(doesn't matter which one). Another word of caution, make sure Repository classes are in different packages for all three databases.
Try adding the following properties:
spring.jpa.generate-ddl=true
You need 2 different persistence factories, not one, each should produce different EntityManagers for different datasources. Also each entity mapping should be marked to been used only with one entity manager.
See full solution here:
http://www.baeldung.com/spring-data-jpa-multiple-databases
I'm a beginner, I have a simple Spring Boot project, it's my first time using a connection pool (HikariCP in this case) and I need your help. It's working but I want to know if I'm using it the right way with Hibernate, or if there are better ways to do it, and if my Spring Boot project structure is correct.
EDIT : It's working even if I remove the class HikariCPConfig, how can I know if connection pools are working or not?
The project is as follow :
- BankManager
src/main/java
|
|__com.manager
|__BankManagerApplication.java
|__HikariCPConfig.java
|__com.manager.dao
|__ClientRepository.java
|__com.manager.entities
|__Client.java
|__com.manager.service
|__ClientServiceImpl.java
|__ClientServiceInterface.java
src/main/resources
|__application.properties
BankManagerApplication.java :
#SpringBootApplication
public class BankManagerApplication {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(BankManagerApplication.class, args);
ClientServiceInterface service = ctx.getBean(ClientServiceInterface.class);
service.addClient(new Client("client1"));
service.addClient(new Client("client2"));
}
}
HikariCPConfig.java :
#Configuration
#ComponentScan
class HikariCPConfig {
#Value("${spring.datasource.username}")
private String user;
#Value("${spring.datasource.password}")
private String password;
#Value("${spring.datasource.url}")
private String dataSourceUrl;
#Value("${spring.datasource.dataSourceClassName}")
private String dataSourceClassName;
#Value("${spring.datasource.poolName}")
private String poolName;
#Value("${spring.datasource.connectionTimeout}")
private int connectionTimeout;
#Value("${spring.datasource.maxLifetime}")
private int maxLifetime;
#Value("${spring.datasource.maximumPoolSize}")
private int maximumPoolSize;
#Value("${spring.datasource.minimumIdle}")
private int minimumIdle;
#Value("${spring.datasource.idleTimeout}")
private int idleTimeout;
#Bean
public HikariDataSource primaryDataSource() {
Properties dsProps = new Properties();
dsProps.put("url", dataSourceUrl);
dsProps.put("user", user);
dsProps.put("password", password);
dsProps.put("prepStmtCacheSize",250);
dsProps.put("prepStmtCacheSqlLimit",2048);
dsProps.put("cachePrepStmts",Boolean.TRUE);
dsProps.put("useServerPrepStmts",Boolean.TRUE);
Properties configProps = new Properties();
configProps.put("dataSourceClassName", dataSourceClassName);
configProps.put("poolName",poolName);
configProps.put("maximumPoolSize",maximumPoolSize);
configProps.put("minimumIdle",minimumIdle);
configProps.put("minimumIdle",minimumIdle);
configProps.put("connectionTimeout", connectionTimeout);
configProps.put("idleTimeout", idleTimeout);
configProps.put("dataSourceProperties", dsProps);
HikariConfig hc = new HikariConfig(configProps);
HikariDataSource ds = new HikariDataSource(hc);
return ds;
}
}
ClientServiceImpl.java
#Service
public class ClientServiceImpl implements ClientServiceInterface {
#Autowired
ClientRepository clientRepository; // this class extends JPARepository
#Override
public Client addClient(Client c) {
return clientRepository.save(c);
}
}
application.properties :
server.port = 8888
spring.jpa.databasePlatform=org.hibernate.dialect.MySQL5Dialect
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = update
spring.datasource.dataSourceClassName=com.mysql.jdbc.jdbc2.optional.MysqlDataSource
spring.datasource.url=jdbc:mysql://localhost:3306/bank_manager
spring.datasource.username=root
spring.datasource.password=
spring.datasource.poolName=SpringBootHikariCP
spring.datasource.maximumPoolSize=5
spring.datasource.minimumIdle=3
spring.datasource.maxLifetime=2000000
spring.datasource.connectionTimeout=30000
spring.datasource.idleTimeout=30000
spring.datasource.pool-prepared-statements=true
spring.datasource.max-open-prepared-statements=250
Thank you in advance.
You project structure is standard, so it's correct.
About Hikari:
Hikari is indeed a great choice for pooling. I'm used to work with Hikari successfully by using a smaller set of params you are applying in your case, but if it's working for you that's fine.
For more info about Hikaru setup, I recommend reading the official wiki, if you haven't already.
About property loading:
You can make use of some SpringBoot features to read the DB parameters and apply into your runtime Beans with less code. Like:
In application.properties (define a custom prefix 'myproject.db' for your pool params)
myproject.db.dataSourceClassName=com.mysql.jdbc.jdbc2.optional.MysqlDataSource
myproject.db.url=jdbc:mysql://localhost:3306/bank_manager
myproject.db.username=root
... and the other params below
Create a Spring Configuration class
#Configuration
public class MyDBConfiguration {
#Bean(name = "myProjectDataSource")
#ConfigurationProperties(prefix = "myproject.db")
public DataSource dataSource(){
//This will activate Hikari to create a new DataSource instance with all parameters you defined with 'myproject.db'
return DataSourceBuilder.create().build();
}
}
In your ClientRepository class:
#Repository
public class ClientRepository {
//The code below is optional, but will work if you want to use jdbctemplate tied to the DataSource created above. By default all Hibernate Sessions will take the DataSource generated by Spring
#Bean(name = "myProjectJdbcTemplate")
public JdbcTemplate jdbcTemplate(#Qualifier("myProjectDataSource") DataSource dataSource){
return new JdbcTemplate(dataSource);
}
}
There are other options to manage the DataSource beans creation if you are going to use 2 or more different Databases. You can vary the properties prefix for the other databases and annotate 1 Datasource only as #Primary, which is mandatory when you have more than 1 DataSources in Spring context