Spring Boot Datasource Setup - java

In Spring Boot - is there anyway to only connect to the database when it is required the first time?
For example - lazy load the database setup?
I understand this is not the usual pattern but would interested in hearing if there is a solution to this
Thanks
Damien

n Spring Boot - is there anyway to only connect to the database when it is required the first time? For example - lazy load the database setup?
Spring Data and Hibernate can do that setup.

I wonder if you can use #Configuration and #Lazy at the same time, and the documentation suggests it is doable but it will create all the bean lazily.
Whereas, if you want to selectively create datasource bean lazily among other beans, then, in that case you need to that use #Lazy on datasource bean
#Configuration
#Lazy
public class YourDataSourceConfigClass {//datasource bean}

Related

Lazy load spring auto configuration

I have dependency in my spring boot project which fetches values of some properties using Spring's EnvironmentPostProcessor.
Now these properties are database credentials and not everyone has access to the credential since there is no dev environment for the db in question. I just want to change the configuration that the credentials don't get fetched on dev or local environment on application startup as that would result in a error and the application will fail to start.
Class A implements EnvironmentPostProcessor{}
I tried to use #Lazy annotation on the Class Annoteted with #ConfigurationProperties. I also tried using my own BeanFactoryPostProcessor (with #Order(HighestPrecedence) to programmatically set the A to lazy load, but it gets called before my BeanFactoryPostProcessor's postProcessBeanFactory method.
Is what I'm trying to achieve possible and am I going about it the wrong way?
#Lazy is only to be used with #Bean or #Component (Or any #Component-based annotations ex. #Service)
Take note: You can also add it to a #Configuration class, but that just means that all Beans in the class are annotated with #Lazy
#Lazy is a bit of a weird annotation in general; it should be seen as an IF possible then lazy load. If some other bean needs the lazy bean, the lazy bean will be initialized. (It's like the Pirate code, more of a guideline than an enforced rule)
Finally, marking #ConfigurationProperties with #Lazy seems a bit odd. As Spring will need these Configuration property "beans" to create the Spring Context.
However, the common use case for #Lazy is a failing database connection, preventing the application from starting. See the question if that is what you are running into.
Summary:
You can configure your repositories to be lazy-loaded with:
spring.data.jpa.repositories.bootstrap-mode=lazy
Last remark (Me just guessing)
If you wish to change properties once your application is already running, I would look at the following tutorial. It goes into manually reloading configuration and also #RefreshScope.
According to documentation EnvironmentPostProcessors must be registered via META-INF/spring.factories:
Allows for customization of the application's Environment prior to the
application context being refreshed. EnvironmentPostProcessor
implementations have to be registered in META-INF/spring.factories,
using the fully qualified name of this class as the key.
Implementations may implement the Ordered interface or use an #Order
annotation if they wish to be invoked in specific order.

Multi-tenency with Spring JPA

We are building a multi-tenant application using spring boot, JPA (Eclipselink). We have done below steps.
Defined AbstractRoutingDatasource
Defined new Bean of LocalContainerEntityManagerFactoryBean for each tenant
Now in our code, we have two types of flavour.
#Persistencecontext
Both do not have a qualifier. Problem is we can not add qualifier example persistence unit name as my tenants will be dynamic.
Is there any way we can solve it. Means on runtime, it will attach the right entity manager with out hardcoding unitname in the persitenceContext
Thanks a lot

How to avoid putting #RefreshScope on multiple beans in my application

We are externalizing configuration of our microservices (spring boot based) using spring cloud.
As per my understanding on Spring Cloud, to enable the beans loading refreshed/updated values from Config server we need to do 2 things in Spring Cloud Client:
add #RefreshScope on the beans reading values from property files
using #Value
add spring actuator to provide /refresh endpoint to
refresh the context.
Scenario:
We have 100s of classes reading values from property file using #Value.
I have to mark all these beans refresh enabled using #RefreshScope annotation.
How can I avoid putting #RefreshScope annotation on all these classes.
Is there any shortcut or spring cloud feature to get around this situation.
You may want to look into Spring Boot feature called #ConfigurationProperties. It is designed to better organize several external configuration options.
According this Github issue, it should work for spring-cloud without #RefreshScope usage.
EDIT (reaction on comment): Maybe you are missing point of #ConfigurationProperties. With this annotation, you wouldn't use it in other configuration classes. You would have dedicated class (or few classes) only for reading and providing properties. Other configuration classes would inject this configuration holder bean.
You could encapsulate your #Values into one (or several) ConfigurationService bean which is #RefreshScoped and autowire this service into your classes instead. That way you only have a small amount of request scoped beans and your services can stay singletons.

Change Java Spring Boot Bean while runtime

Hello fellow developers,
i created a library using the Spring boot framework.
This library is creating a dynamic database connection using #Beans where i create a "data" Bean which holds the unlimited Datasource beans provided by a Postgresql db. At the end i wanted to have a dynamic db connection which could be triggered from outside to change the db i want to connect to. The information of the different databases where stored as mentioned inside of a postgres. This is loaded at the application start into this bean. My Problem is, that i'm not able to switch between the different Datasource beans. Spring boot is creating them, but it seems like it's not possible to change the bean started at runtime of the application which only holds one of the unlimited Datasources... So also after a retriggering of the creation of the original bean it still uses the old datasource.
Is there a way to use the beans from spring boot and change them on runtime?
Regards,
Andreas
I believe you are asking for DB multitenancy support where tenants information is stored in a Postgres DB.
Configuring the persistent layer for multi-tenancy support involves configuring:
Hibernate, JPA and Datasources properties
Datasources beans
Entity manager factory bean
Transaction manager bean
Spring Data JPA and annotation-driven transactions
I recently blog about Multi-tenant applications using Spring Boot, JPA, Hibernate and Postgres and although the tenants data is stored in a yml "properties" file, it shouldn't be difficult to convert it to read tenant data from a DB. I think it would be a starting point for what you would like to accomplish.

Spring boot and flyway integration - init order

I have an EntityManager (and a DataSource) created by spring boot and i want to add flyway. but EntityManager must be created after flyway and flyway after the DataSource. do i have to create whole EntityManager manually only to add 'depends-on' or is there some simpler way?
Boot doesn't create a Hibernate SessionFactory so probably you mean a JPA EntityManager. If you create your own Flyway it will always be initialized before the Boot autoconfig beans. Is that not what you see? Maybe you need to share a project.
The problem is in the usage of spring.jpa.hibernate.ddl-auto=validate (Hibernate wants to validate the DataSource before the migrations are executed, see here). A simple workaround is to switch to spring.jpa.hibernate.ddl-auto=none.

Categories