Spring Boot and Spring Session: How to control the DataSource - spring

I'm experimenting with Spring Boot and Spring session together, specifically using JDBC.
Just adding the line in application.properties:
spring.session.store-type=jdbc
made it just work, which is nice because I happen to also have some data source properties in that file, ie
myapp.datasource.url=jdbc:mysql://localhost/etc...
myapp.datasource.driver-class-name=com.mysql.jdbc.Driver
But I'm actually using those for my own data source with my own configuration, like so:
#Configuration
#PropertySource("classpath:credentials.properties")
public class DataSourceConfig {
#Primary
#Bean(name = "dataSource")
#ConfigurationProperties(prefix = "myapp.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
}
and as far as I can tell, Spring Session is creating its own data source instead of using mine. Is there a way I can get it to use mine instead?
(my real data source has some additional configs with Hikari not shown here)

Spring Session itself does not create DataSource but rather uses the one present in your application context, if it's the either:
the only DataSource bean
DataSource marked as #Primary
Also if you wish to use a specific DataSource for Spring Session (for example, if you have multiple DataSources in your application) you can do that by:
annotating DataSource marked as designated for Spring Session by #SpringSessionDataSource (Spring Session 2.0 onwards)
providing JdbcTemplate bean that uses the desired DataSource and naming it springSessionJdbcOperations (Spring Session 1.x)
The Spring Session JDBC configuration capabilities and logic should be quite easy to understand from the JdbcHttpSessionConfiguration.

Related

spring-boot-starter-quartz specify different db connector?

I have a spring boot application that is working correctly
with quartz job that is working correctly
all quartz related tables are created on FOO schema that is specified in the application.properties
spring.datasource.url=
spring.datasource.username=
spring.datasource.password=
how do I specify a different DB schema only for the quartz objects?
To use another datasource for quartz-schedulers you have to create a bean data-source annotated with #QuartzDataSource
#Bean
#QuartzDataSource
public DataSource dataSource() {
...
}
To have Quartz use a DataSource other than the application’s main DataSource, declare a DataSource bean, annotating its #Bean method with #QuartzDataSource. Doing so ensures that the Quartz-specific DataSource is used by both the SchedulerFactoryBean and for schema initialization.
Related docs: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-quartz.html

Initialize standalone databases, Spring Boot and MyBatis

I'm building Spring Boot + MyBatis project using standalone postgresql database.
Well, for some reason, "convention-based" database initialization doesn't occur. I added data source manually, created sql-scripts, but when I run the project, from the log it's not even processing these scripts. I want to understand how the process works for not-embedded databases.
Can one create an instance of data source using code?
Should I link data source in property file or separate class?
What one should do to link separate data source (postgresql in this case) with Spring Boot configuration?
Yes
#Bean
public DataSource dataSource() {
DataSourceBuilder.create()
.url("jdbc:postgresql://localhost:5432/database")
.username("username")
.password("password")
...
.build();
}
2-3. You can use property file along with providing java based DataSourceConfiguration
spring.datasource.url: jdbc:postgresql://localhost:5432/database
spring.datasource.username: username
spring.datasource.password: pasword
And refers these properties in your Configuration class as follows:
#Bean
#ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
If you have only one database to connect to, the most convenient way is to add it's connection properties into property file, prefixed with spring.datasource (scroll here to check available options) and add org.postgresql dependency to pom.xml (build.grade) file and SpringBoot will do the rest.

Using #ConfigurationProperties in Spring Boot Application doesn't work

I am using Spring Boot V 1.4.1 for a new application.
My app requires two JDBC data sources and I was following the example at http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-two-datasources how to set it up.
My Spring beans configuration class is annotated with #EnableConfigurationProperties and my first bean is defined as
#Primary
#Bean
#ConfigurationProperties(prefix = "first.database")
DataSource qivsDB() {
return DataSourceBuilder.create().build();
}
, the second one accordingly. My application.properties file has properties defined like
first.database.url=jdbc:[redacted]
first.database.username=[redacted]
first.database.password=[redacted]
For reasons I not transparent to me during debugging this is failing to initialize: Cannot determine embedded database driver class for database type NONE - debug showed me that the builder does not have any properties set when calling build().
What did I miss here?
Before you do all the debugging part, you should have a look to the auto-configuration report. If you define your own DataSource there's no reason for Spring Boot to start looking at what it can do for your app. So, for some reasons, that definition of yours is not applied in your app and the default in Spring Boot still applies, doesn't find any JDBC url in the default namespace and attempt to start an embedded database. You should see in the auto-config report that the DataSourceAutoConfiguration still matches.
I am not sure the public keyword has anything to do with it, though you won't get custom meta-data for that key since we only scan for public methods.

SpringBoot Datasource AutoConfiguration Not Working

I have a simple SpringBoot application and I'd like to use AutoConfiguration to configure the Tomcat jdbc pooled data sources.
I am using these Spring dependencies:
// Spring Boot
compile 'org.springframework.boot:spring-boot-starter-web:1.3.5.RELEASE'
compile 'org.springframework.boot:spring-boot-starter-jdbc:1.3.5.RELEASE'
Here are my datasource properties in my application.yml file:
spring:
datasource:
url: jdbc:mysql://my.host/mydb
username: user
password: pwd
driver-class-name: com.mysql.jdbc.Driver
initialSize: 5
I am sure the properties are being loaded because the app is picking up other values.
I define the bean in my config file as:
#Bean(name="myDataSource")
#ConfigurationProperties(prefix="spring.datasource")
public DataSource getDataSource() {
DataSource dataSource = DataSourceBuilder.create().build()
return dataSource
}
And I inject the datasource into my DAO like this:
#Slf4j
#Repository
class MyDAO {
#Autowired
DataSource dataSource
public void getFoo() {
log.info("DB URL: ${dataSource.getUrl()}")
}
}
If I set a breakpoint in the getDataSource() method, the DataSourceBuilder will create an instance of DataSource. However, all the properties of that object like URL, user and password are all null. Also, when I call getFoo(), the dataSource variable is null. I have tried commenting out the bean definition in my AppConfig. The dataSource is still null. Any suggestions?
I looked through the Spring Boot documentation and my Spring book but I didn't see any examples like this. I see examples where I create the DataSource myself. But I was hoping Spring's auto-configuration would tie this stuff together automatically.
Thanks in advance for any help you can provide.
By creating your own bean, you're actually switching off Boot's auto-configuration of a DataSource. You can just delete your getDataSource method and let Boot auto-configure one instead.
Based on Andy's comments I found out that I had two problems. First of all, I needed to include the JPA dependency to the project. I added this line to my build.gradle file:
compile 'org.springframework.boot:spring-boot-starter-data-jpa:1.3.5.RELEASE'
Second, I was creating instances of MyDAO using new(). I fixed this by creating a service class that used #Autowired to inject an instance of MyDAO. Once the DAO became a Spring managed bean, it was able to inject the instance of DataSource from the Tomcat connection pool.

Spring Boot with Legacy tables

I want to use Spring Boot with Legacy database and use hibernate for the same. I have to access both DB2 and Teradata as data sources.I would like to know if this is possible ? I'm a newbie to Spring , SpringBoot and have no idea how to configure data sources , should i still need multiple xml configs etc. The demos in spring io sites are good but they dont deal with any of my requirement. Kindly point me in the right direction.
In Spring Boot it is very easy to configure multiple datasources. This part of the documentation describes the procedure in detail.
In essence, all you need to do is have the connection properties in a place where Spring boot can locate them (the easiest place is application.properties) and then configure the beans. The code would look like:
application.properties
datasource.primary.url=jdbc:mysql://localhost/test
datasource.primary.username=dbuser
datasource.primary.password=dbpass
datasource.secondary.url=jdbc:mysql://localhost/test2
datasource.secondary.username=dbuser2
datasource.secondary.password=dbpass2
Spring configuration file
#Bean
#Primary
#ConfigurationProperties(prefix="datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
#Bean
#ConfigurationProperties(prefix="datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
You will notice that no XML configuration is used which the preferred style these days. Actually using Spring Boot means that you don't have to write almost any configuration :)

Resources