Spring-Boot / H2 Write database snapshots to file-system - java

I am working on my Spring-Boot-Application that is using a database.
I want to give the user the option to use an embedded database (for quick testing) or a hard-drive-based database (for long term usage).
My way is to add a bool flag to the application.properties, read this in the config and create the wanted DataSource.
#Bean
public DataSource dataSource() {
if (embedded) {
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
EmbeddedDatabase db = builder
.setType(EmbeddedDatabaseType.H2)
.addScript("db.sql")
.build();
return db;
} else {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(databaseURL);
dataSource.setUsername(databaseUser);
dataSource.setPassword(databasePassword);
return dataSource;
}
}
This is working just fine. My problem right now is that I want to persist the embedded-database between sessions, and load its content again if the application is starting again (if the user used embedded database before, and is using it again so he isnt loosing his data)
What do I need to add to my code to make the database create snapshots and use them again if starting up?
Greetz and thanks for your help,
Patrick

You configure it though connection URL.

Related

Tables are getting refreshed after re-executing the application with EmbeddedDatabaseBuilder using derby

I am using Spring Boot and Spring JDBC with Derby. Below is the code snippet to initialize the embedded Database.
#Bean
public DataSource dataSource() {
// no need shutdown, EmbeddedDatabaseFactoryBean will take care of this
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
EmbeddedDatabase db = builder
.setType(EmbeddedDatabaseType.DERBY) //.H2 or .DERBY
.addScript("db/sql/create-db.sql")
.addScript("db/sql/insert-data.sql")
.build();
return db;
}
But when I am running the application the tables are getting dropped and created each time. So all the data inserted in last run was flushed. I don't want to drop the tables. How can I achieve this?
set the below property in your application.properties/application.yml
spring.jpa.hibernate.ddl-auto=update
As per spring documentation here
spring.jpa.hibernate.ddl-auto
DDL mode. This is actually a shortcut for the "hibernate.hbm2ddl.auto"
property. Defaults to "create-drop" when using an embedded database
and no schema manager was detected. Otherwise, defaults to "none".
As you are using embedded database, it is defaulting to create-drop

Spring - Change schema connection for persistent_logins

I am working on a Spring Boot web application and I am implementing the "Remember me" function.
I defined in my Web Security Configuration this:
http.authorizeRequests().and()
.rememberMe().tokenRepository(this.persistentTokenRepository())
.tokenValiditySeconds(1 * 24 * 60 * 60); // 24h
and
#Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl db = new JdbcTokenRepositoryImpl();
db.setDataSource(dataSource);
return db;
}
The problem is that when I flag the option on the html page, Spring try to add a token in the default schema of my database -> "public".
Is there any way to change the default schema for that option? Everything else is linked correctly on the right schema through this property:
spring.jpa.properties.hibernate.default_schema=another_schema_name
I tried to make a personal implement of the class JdbcTokenRepositoryImpl but I can't find a way to change the schema. I looked it up online but I didn't find nothing..
Thank you
Regards,
Mohamad
You may initialize differently your dataSource variable what you use in your PersistentTokenRepository bean. Most data sources support schema setting. For instance Spring's org.springframework.jdbc.datasource.DriverManagerDataSource :
#Bean(name = "dataSource")
public DataSource getDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
// ... tipicly set username, password, driver class name, jdbc Url
dataSource.setSchema(schema);
return dataSource;
}
You could control the schema through the mentioned property: (spring.jpa.properties.hibernate.default_schema)
#Value("${spring.jpa.properties.hibernate.default_schema}")
private String schema;

how to extenalize db connection stuff

I am new in Java Spring framework and related technologies. I want to externalize the database stuff like connection string, username and password in a different file so that incase there is change in the database username and or password, I can go an change without touching the war file and recompiling the application. Right now all the application I am supporting was hardcoded
Any help will be appreciated. NB we are oracle shop
Use properties files.
This is an example of configuring Oracle database:
spring.datasource.url=jdbc:oracle:thin:#localhost:1522:orcl
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver.class=oracle.jdbc.driver.OracleDriver
and in your config class file use something like:
#Primary
public DataSource userDataSource() {
DriverManagerDataSource dataSource
= new DriverManagerDataSource();
dataSource.setDriverClassName(
env.getProperty("spring.datasource.driver.class"));
dataSource.setUrl(env.getProperty("spring.datasource.url"));
dataSource.setUsername(env.getProperty("spring.datasource.username"));
dataSource.setPassword(env.getProperty("spring.datasource.password"));
return dataSource;
}
Depending on your needs, there are a lot of tutorials on the web. Check for example:
https://www.programmergate.com/spring-boot-jpa-hibernate-oracle/

Dynamic Database property changes in Springboot

I have mysql database and i have configured database properties in application.properties file .
Now if i do change db connection properties , i want reflect that changes into my application on the fly , means with out restarting the server
Is this possible using with spring cloud config server and actuator?
I have tested this quite a bit and here are my findings.
Spring config server works pretty well for simple key value pairs.
It also works for Database properties provided that you are creating datasource objects yourself and you are using #RefreshScope.
For example, if you have a config server with these properties.
mongodb.feed.database=kiran
mongodb.feed.host=localhost
mongodb.feed.port=27017
And you are configuring MongoTemplate in your application like this.
#Configuration
#ConfigurationProperties(prefix = "mongodb.feed")
#EnableMongoRepositories(basePackages = "in.phani.springboot.repository", mongoTemplateRef = "feedMongoTemplate")
#Setter
class FeedMongoConfig {
private String host;
private int port;
private String database;
#Primary
#Bean(name = "feedMongoTemplate")
#RefreshScope // this is the key
public MongoTemplate feedMongoTemplate() throws Exception {
final Mongo mongoClient = createMongoClient(new ServerAddress(host, port));
return new MongoTemplate(mongoClient, database);
}
Mongo createMongoClient(ServerAddress serverAddress) {
return new MongoClient(serverAddress);
}
}
And if you change the database name in your config properties and then refresh the scope with /refresh endpoint. It works pretty well.
With springboot you need not do manual configuration like this. Spring boot has Autoconfiguration for most of the stuff. Continuing with the same example above, if you were to put in config properties something like this
spring.data.mongodb.uri=mongodb://localhost:27017/phani
spring-boot will configure MongoTemplate for you(you don't need to create yourself as in 2nd point).
Here comes the hiccup.
Now if you change the database name, and refresh the scope, it doesn't work. Because in this case, MongoTemplate was configured by spring-boot Autoconfiguration(MongoAutoConfiguration)
So in conclusion, it needs extensive testing to be done, before using it on production(especially for complex beans like datasources, MongoTemplates), since there is not enough documentation on this.. But I would say, it is worth trying.

Spring multiple Data Source configuration - Auto Fail over mechanism

I would like to know if Spring offers any support for Auto Fail over of Data Sources? For example, if the primary data source is down, connect to secondary. Any suggestions to effectively configure auto fail over of Data sources is greatly appreciated.
Thanks.
The Primary/DR setup for DB should be managed at DB level. Its not right to switch that in code. But to answer your question "can connect to 2 Data sources in Spring". Yes you can easier if you are using Spring-boot.
Few details from spring documentation.
Mark one of them as #Primary if you are using the default auto-configuration for JDBC or JPA (then that one will be picked up by any #Autowired injections).
#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();
}

Categories

Resources