Creating Datasource Dynamically in SpringBoot OpenJPA Application (Implementing Multitenancy with OpenJPA) - postgresql

I am creating a Springboot application with OpenJPA.
My requirement is that I need to connect to multiple datasources dynamically and the datasource credentials are obtained at runtime by calling some rest-endpoints.
Here is the controller class:
#RestController
public class StationController {
#Autowired
BasicDataSource dataSource;
I have a service which returns me the jdbc_url depending on the customer name:
public String getDSInfo(String customername){
// code to get the datasource info (JDBC URL)
}
My questions are:
Is there a way in which I can create datasources at runtime by getting datasource credentials by calling some other service (which takes the customer id and returns the customer specific datasource) ?
Since my application is a web based application, many customers will be accessing it at the same time, so how to create and handle so many different datasources?
NOTE:
The code will get information about the customer specific data source only by firing some service at the runtime, so I cannot hardcode the datasource credentials in the XML configuration file.
I found some implementations with Hibernate but i am using Springboot with OpenJPA. So need OpenJPA specific help.

It sounds like you want a multi-tenancy solution.
Datasources are easy to create programmatically, just use a DataSourceBuilder with your connection details pulled in from a central source (e.g. a central config database or Spring Config Server).
Then you'll need to look at a multi-tenancy framework to tie the datasources back to clients.
See here:
https://www.youtube.com/watch?v=nBSHiUTHjWA
and here
https://dzone.com/articles/multi-tenancy-using-jpa-spring-and-hibernate-part
The video is a long watch but a good one. Basically you have a map of customer data sources (from memory) that allow an entityManager to pick up a datasource from the map by using a thread scoped custom spring scope of "customer" which is set when a user for a particular customer somehow logs into your app.

Related

Mark a field as transient for one datasource but not another in spring data jpa

I've got an app that sends data to SQL Server, and we'd like to expand it to also write to another data source (possibly amazon s3, but possibly a regular database). The issue is, this new database only needs a subset of the fields in my entity class.
Is there a way that I can mark a field as being transient for one datasource but not another? Or should I be doing something on the Repository level? I'm using Spring Data JPA, and had been using a Spring-generated JpaRepository.
public interface JobRepository extends JpaRepository<MyPojo, Long>{}
It is possible to create two different repository interfaces for two different data sources. In this case, you will need to create two different entities-one for each data source and bind them in your services.
For Data Source A: AEntity, ARepository
For Data Source B: BEntity, BRepository
And in your services, you create a method:
public AEntity createAEntityFromBEntity(BEntity bEntity);
To be able to do this, you will need to mark one of your data sources as #Primary. Please check this link to see how to create two different data source connections with configuration details.

What are the DAO, DTO and Service layers in Spring Framework?

I am writing RESTful services using spring and hibernate. I read many resource in internet, but they did not clarify my doubts. Please explain me in details what are DAO, DTO and Service layers in spring framework? And why usage of these layers is required in spring to develop RESTfull API services.
First off, these concepts are Platform Agnostic and are not exclusive to Spring Framework or any other framework, for that matter.
Data Transfer Object
DTO is an object that carries data between processes. When you're working with a remote interface, each call it is expensive. As a result you need to reduce the number of calls. The solution is to create a Data Transfer Object that can hold all the data for the call. It needs to be serializable to go across the connection. Usually an assembler is used on the server side to transfer data between the DTO and any domain objects. It's often little
more than a bunch of fields and the getters and setters for them.
Data Access Object
A Data Access Object abstracts and encapsulates all access to
the data source. The DAO manages the connection with the data source to
obtain and store data.
The DAO implements the access mechanism required to work with the data source.
The data source could be a persistent store like an RDBMS, or a business service accessed via REST or SOAP.
The DAO abstracts the underlying data access implementation for the Service objects to
enable transparent access to the data source. The Service also delegates
data load and store operations to the DAO.
Service
Service objects are doing the work that the
application needs to do for the domain you're working with. It involves calculations based on inputs and
stored data, validation of any data that comes in from the presentation, and figuring out exactly what data
source logic to dispatch, depending on commands received from the presentation.
A Service Layer defines an application's boundary and its set of available operations from
the perspective of interfacing client layers. It encapsulates the application's business logic, controlling
transactions and coordinating responses in the implementation of its operations.
Recommended References
Martin Fowler has a great book on common Application Architecture Patterns named Patterns of Enterprise Application Architecture. There is also, Core J2EE Patterns that worth looking at.
DAO - Data Access Object:
An object that provides a common interface to perform all database operations like persistence mechanism.
public interface GenericDao<T> {
public T find(Class<T> entityClass, Object id);
public void save(T entity);
public T update(T entity);
public void delete(T entity);
public List<T> findAll(Class<T> entityClass);
}
See this example : Spring – DAO and Service layer
DTO - Data Transfer Object:
An object that carries data between processes in order to reduce the number of method calls means you combine more than one POJO entities in service layer.
For example a GET request /rest/customer/101/orders is to retrieve all the orders for customer id 101 along with customer details hence you need combine entity Customer and entity Orders with details.
Enterprise application is divided into tiers for easy maintenance and development. Tiers are dedicated to particular type of tasks like
presentation layer (UI)
Business layer
Data access layer (DAO, DTO)
Why this design:
Let's pick an example you have an application which reads data from db and performs some business logic on it then present it to user. Now if you want to change your DB let say earlier application was running on Oracle now you want to use mysql so if you don't develop it in tiers you will doing changes everywhere in application. But if you implement DAO in application then this can be done easily
DAO: Data Access Object is design pattern
just provide an interface for accessing data to service layer and provide different implementations for different data sources (Databases, File systems)
Example code:
public interface DaoService {
public boolean create(Object record);
public CustomerTemp findTmp(String id);
public Customer find(String id);
public List getAllTmp();
public List getAll();
public boolean update(Object record);
public boolean delete(Object record);
public User getUser(String email);
public boolean addUser(User user);
}
Service layer using Dao
#Service("checkerService")
public class CheckerServiceImpl implements CheckerService{
#Autowired
#Qualifier("customerService")
private DaoService daoService;
Now i can provide any implementation of DaoService interface.
Service and DTO are also used for separation of concerns.
DTO: The data object that we pass between different processes or within the same process. It can be a wrapper around the actual entity object. Using entity object as is for DTO is not safe and not recommended. Design of this object is based on various factors like simplicity of representation, security of exposing Ids, consumer requirement and so on.
In Spring, DTO can be formed with a simple model/pojo object.
DAO: The object responsible for CRUD operations.
In Spring, this can be an object that implements JPARepository interface, or any bean that connects with database and does a CRUD for us. Please remember your journey from JDBC to Hibernate to Spring data JPA. :)
Service: Core bean for business logic implementation. This object may has DAO object as its dependency. Core business logic for the particular use case will go here.
In Spring, Service object/bean can be created either by annotating the bean with #Service or #Component annotation or simply representing the object as a bean using java configuration. Make sure you inject all the required dependencies into the service bean for its heavy lifting job.
SERVICE LAYER:
It receives the request from controller layer and process the request to Persistence layer
#Controller:It is the annotation which initialize whole controller layer.
#Service:It is the annotation which initialize whole service layer.
#Repository: It is the annotation which initialize whole persistence layer.
DTO:
It is an Data Transfer object which used to pass the properties from service layer to persistence layer.
DAO:
It is an Data Access object. it is also known as persistence layer. In this DAO we receive property values from service layer in DTO object. Here we write an persistence logic to db.

How does Spring Data know wicht store to back a repository with if multiple modules are used?

In a Spring Data project if I am using multiple types of repositories i.e JPA repository and Mongo repository and if I am extending CrudRepository then how does Spring Data know which store to choose for that repository? It can use JPA or Mongo. Is it based on the annotation #Document or #Entity added on every persisting entity?
The decision which store a proxy created for a Spring Data repository interface is only made due to your configuration setup. Assume you have the following config:
#Configuration
#EnableJpaRepositories("com.acme.foo")
#EnableMongoRepositories("com.acme.foo")
class Config { }
This is going to blow up at some point as the interfaces in package com.acme.foo are both detected by the MongoDB and JPA infrastructure. To resolve this, both the JavaConfig and XML support allows you to define include and exclude filters so that you can either use naming conventions, additional annotations or the like:
#Configuration
#EnableJpaRepositories(basePackages = "com.acme.foo",
includeFilters = #Filter(JpaRepo.class))
#EnableMongoRepositories(base Packages = "com.acme.foo",
includeFilters = #Filter(MongoRepo.class))
class Config { }
In this case, the two annotations #JpaRepo and #MongoRepo (to be created by you) would be used to selectively trigger the detection by annotating the relevant repository interfaces with them.
A real auto-detection is sort of impossible as it's hard to tell which store you're targeting solely from the repository interface declaration and at the point in time when the bean definitions are created we don't even know about any further infrastructure (an EntityManager or the like) yet.

How to read the schema used by a JPA implementation

My EntityManager is using a persistence unit that uses a data source provided by our Websphere configuration. The DS configuration includes an environment specific DB to use.
The EM successfully uses this schema, but I can't figure out a way to log or display the schema being used. I was thing something like em.getCurrentSchema would be available..
Any help would be great, thanks.
No API to do this (in JPA). You could do it via JDBC and use of DatabaseMetaData.
JPA is to provide an object view of the data and ease persistence of those objects, not to just present datastore specifics to the user.

Dynamicly select datasource for entities runtime

I have an entity bean that will represent an expected result over multiple databases/datasources and can also be different queries executed, but same result always comming back. So the bean is re-used over different datasources that should be able to be dynamicly selected.
Is it possible with JPA to select during runtime the data source to be used to execute a query, and return the same type of entity bean?
Also, does my ejb/application need to define the datasources that will be used? Or can I always specify via jndi what datasource to use? Modifying the descriptor's and re-deploying an application everytime a new datasource is created is not an option.
Sorry if the question does not make 100% sense, rather difficult to get the idea through.
Is it possible with JPA to select during runtime the data source to be used to execute a query, and return the same type of entity bean?
You can't change the datasource of a persistence unit at runtime. However, you can configure several persistence unit and use one or another EntityManagerFactory. Maybe JPA is not the right tool for your use case.
Modifying the descriptor's and re-deploying an application everytime a new datasource is created is not an option.
And how will the application be aware of the "available datasources"?
You can change the JPA datasource at runtime, but the approach is tricky (introspection, JPA implementation specific, ...).
I've implemented my own implementation of javax.persistence.spi.PersistenceProviderwhich override the org.hibernate.ejb.HibernatePersistence and sets the datasource in both the Map and PersistenceUnitInfo of the PersistenceProvider just before creating the EntityManagerFactory. This way, my EntityManagerFactory has a datasource which has been configured at runtime. I keep my EntityManagerFactory until the application is undeployed.
You could use the same be approach and create N different EntityManagerFactory, each with its specific datasource. However keep in mind that each ÈntityManagerFactory uses a lot of memory.