I need to refresh my Redis cache every time some insert/update happens in the DB through a flyway migration script. Is there any way to achieve this? My application is written in Spring Boot.
You can use help of cacheManager.
public void clearCache() {
cacheManager.getCacheNames()
.parallelStream()
.forEach(n -> cacheManager.getCache(n).clear());
}
Also check for documentation.
RedisCacheManagerBuilder
Related
JaversBuilder.build() always calls MongoRepository.ensureSchema() to execute createIndex() for jv_snapshots, even when the indexes already exists.
Particularly, the createIndex permission was revoked because this command blocks all other operations on the Mongo instance (not only the database, like in MongoDB documentation) when executed in foreground.
Maybe ensureSchema could be called when configuring Javers for the application, outside JaversBuilder.build(). Example:
#Bean
public Javers javers() {
MongoRepository repository = new MongoRepository(mongoClient.getDatabase(databaseName));
Javers javers = JaversBuilder.javers().registerJaversRepository(repository).build();
repository.ensureSchema();
return javers;
}
It is appropriate to suggest the removal of the call to ensureSchema from JaversBuilder.build() or is there another way to avoid index creation on startup in a non Spring Boot application?
Is there any way to refresh springboot configuration as soon as we change .properties file?
I came across spring-cloud-config and many articles/blogs suggested to use this for a distributed environment. I have many deployments of my springboot application but they are not related or dependent on one another. I also looked at few solutions where they suggested providing rest endpoints to refresh configs manually without restarting application. But I want to refresh configuration dynamically whenever I change .properties file without manual intervention.
Any guide/suggestion is much appreciated.
Can you just use the Spring Cloud Config "Server" and have it signal to your Spring Cloud client that the properties file changed. See this example:
https://spring.io/guides/gs/centralized-configuration/
Under the covers, it is doing a poll of the underlying resource and then broadcasts it to your client:
#Scheduled(fixedRateString = "${spring.cloud.config.server.monitor.fixedDelay:5000}")
public void poll() {
for (File file : filesFromEvents()) {
this.endpoint.notifyByPath(new HttpHeaders(), Collections
.<String, Object>singletonMap("path", file.getAbsolutePath()));
}
}
If you don't want to use the config server, in your own code, you could use a similar scheduled annotation and monitor your properties file:
#Component
public class MyRefresher {
#Autowired
private ContextRefresher contextRefresher;
#Scheduled(fixedDelay=5000)
public void myRefresher() {
// Code here could potentially look at the properties file
// to see if it changed, and conditionally call the next line...
contextRefresher.refresh();
}
}
I am new to Spring Batch programming and stucked in following scenario.
I have a Spring Batch application, and I want to run a SQL INSERT script everytime the app starts.
Scenario :
My Spring batch application has 2 databases - (1) HSQL and (2) MySQL
All the tables that are internal to spring batch are created in HSQL and all the tables required for application are present in MySQL. I want to run a INSERT SQL script in MySQL everytime a application starts.
I went through many of the articles, and as suggested in most of the articles created data.sql and data-mysql.sql and ran my app. But it tries to search the table in HSQL and throws Object not found exception.
Is there any way I can execute a SQL script so that it will try to connect to MySQL and then do inserts.
Help is highly appreciated.
Thanks in advance
Saurabh
You can use JobExecutionListener.beforeJob Listener along with Spring ScriptUtils
Sample Code:
public class MyobListener implements JobExecutionListener {
#Autowired
Private DataSource yourMySQLDataSource
//This method will be called before job get started
#Override
public void beforeJob(JobExecution jobExecution) {
ScriptUtils.executeSqlScript(yourMySQLDataSource.getConnection(), new ClassPathResource("your.sql"));
}
#Override
public void afterJob(JobExecution jobExecution) {
}
}
Reference : ScriptUtil
I am trying to use flyway for DB migrations and Spring boot's flyway support for auto-upgrading DB upon application start-up and subsequently this database will be used by my JPA layer
However this requires that schema be present in the DB so that primary datasource initialization is successful. What are the options available to run a SQL script that will create the required schema before flyway migrations happen.
Note that If I use flyway gradle plugin (and give the URL as jdbc:mysql://localhost/mysql. It does create the schema for me. Am wondering if I could make this happen from Java code on application startup.
Flyway does not support full installation when schema is empty, just migration-by-migration execution.
You could though add schema/user creation scripts in the first migration, though then your migration scripts need to be executed with sysdba/root/admin user and you need to set current schema at the beginning of each migration.
If using Flyway, the least problematic way is to install schema for the first time manually and do a baseline Flyway task (also manually). Then you are ready for next migrations to be done automatically.
Although Flyway is a great tool for database migrations it does not cover this particular use case well (installing schema for the first time).
"Am wondering if I could make this happen from Java code on application startup."
The simple answer is yes as Flyway supports programmatic configuration from with java applications. The starting point in the flyway documentation can be found here
https://flywaydb.org/documentation/api/
flyway works with a standard JDBC DataSource and so you can code the database creation process in Java and then have flyway handle the schema management. In many environment you are likely to require 2 steps anyway as the database/schema creation will need admin rights to the database, while the ongoing schema management will need an account with reduced access rights.
what you need is to implement the interface FlywayCallback
in order to kick start the migration manually from you code you can use the migrate() method on the flyway class
tracking the migration process can be done through the MigrationInfoService() method of the flyway class
Unfortunately if your app has a single datasource that expects the schema to exist, Flyway will not be able to use that datasource to create the scheme. You must create another datasource that is not bound to the schema and use the unbounded datasource by way of a FlywayMigrationStrategy.
In your properties file:
spring:
datasource:
url: jdbc:mysql://localhost:3306/myschema
bootstrapDatasource:
url: jdbc:mysql://localhost:3306
In your config file:
#Bean
#Primary
#ConfigurationProperties("spring.datasource")
public DataSourceProperties primaryDataSourceProperties() {
return new DataSourceProperties();
}
#Bean
#Primary
#ConfigurationProperties("spring.datasource")
public DataSource primaryDataSource() {
return primaryDataSourceProperties().initializeDataSourceBuilder().build();
}
#Bean
#ConfigurationProperties("spring.bootstrapDatasource")
public DataSource bootstrapDataSource() {
return DataSourceBuilder.create().build();
}
And in your FlywayMigrationStrategy file:
#Inject
#Qualifier("bootstrapDataSource")
public void setBootstrapDataSource(DataSource bootstrapDataSource) {
this.bootstrapDataSource = bootstrapDataSource;
}
#Override
public void migrate(Flyway flyway) {
flyway.setDataSource(bootstrapDataSource);
...
flyway.migrate()
}
I am looking for a way to auto insert a default admin account, using JPA, when my spring mvc application is deployed.
My database is generated based on the Entities.
I want to kick off something that will insert a default admin user, assign roles, every time the application is deployed.
It depends on which implementation of JPA you use.
If you use Hibernate you can add import.sql file (that contains records to load) to the class path. More info here.
As a workaround you can also use dbunit tool.
I would recommend having a migration utility that will keep your database in synch with your codebase - these are typically DDL's, but again the queries to insert default admin user, assign roles etc can also be part of this migration utility. There are very good one's available - Flyway is one that I have used, Liquibase is another one.
There is a very good comparison of the different migration utilities on the Flyway homepage also that you can look at.
i use CommandLineRunner interface.
#Component
public class CommandLineAppStartupRunner implements CommandLineRunner {
#Autowired
UserRepository userRepository;
#Override
public void run(String...args) throws Exception {
User admin = new user(firstName);
userRepository.save(admin);
}
}
before the app starts this class will be executed.
you can find other ways here : Guide To Running Logic on Startup in Spring