How to get hold of Connection object in spring data jpa? - spring-data-jpa

I am using HikariDatasource as connection pool with Spring data JPA.
How do i get hold of the connection object in my code?
Is there any way to do it? I need to unlock jdbc driver after I get the connection.

The solution is to extend HikariDataSource class and override the getConnection() method. Supply this wrapper class to the DataSource bean.

Related

Change spring data r2dbc context to use R2dbcRepositories in a different database

How can I change spring data r2dbc repositories target-datatabase (maybe I am talking about 'Context')?
Let me explain better.
I am managing(ConnectionFactory Properties) 'connection factory' to execute SQL-DDL scripts in any database I want - OK; however, R2dbcRepositories (REactiveCruRepository) methods, are not follow this database I have configured ConnectionFactory Properties.
How Can I change ConnectionFactory Properties, in order to, REactiveCruRepository points for this configuration done (meaning a new database)?
It is very easy to configure another connection factory for your R2dbc Repositories.
Check my example about multiple R2dbc connection factories.

If a #Transactional annotated method is called from another #Transactional annotated method, does this result in two connections being consumed?

Off late, we have been getting hikari connection pools getting exhausted more than a couple of times. The exception being thrown is as follows:
"org.springframework.transaction.CannotCreateTransactionException:
Could not open JDBC Connection for transaction;
nested exception is java.sql.SQLTransientConnectionException:
HikariPool-1 - Connection is not available, request timed out after 30000ms."
What I have observed is that some unaware developers have added #Transactional annotation to a lot of simple get calls on the DB (Postgres).
We use JdbcTemplate to make DB calls with a default connection pool size of 10.
The public endpoints at the controllers are already annotated as #Transactional. Can adding the #Transactional annotation to the DAO Beans result in creation of nested connections when the service layer, which is a seperate bean, which calls the DAO layer is already #Transactional.
We also have a few scheduled CRON jobs, and I see that these are not exposed via a public api or exposed via a controller, but do I still need to add #Transactional to the parent level methods in such cron/internal methods to be able to optimally make db calls? We are not expecting changes to roll back for these cron jobs. We already use JdbcTemplate which uses Hikari Connection poo. Is #Transactional need at all in such cases to optimise performance.
All configurations are default spring boot configurations, so default Tx.Type is REQUIRED unless explicitly set.
#Transactional should be mainly use in service layer when you are about to use database connections, it should be used on minimum methods that represent a business flow.
I think you are over using it and may create unnecessary connections, thus create timeout on overloaded pool
Notice that you use only one database connection pool,as HikariCP, and not also PGBouncer for example.
Also see more performance/configuration tweaks for HikariCP in its wiki page

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

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.

compare two EntityManagerFactories for having PersistenceUnits with identical connection attributes

Having two JPA2 (EclipseLink) EntityManagerFactory instances what would be the best way to detect that their PersistenceUnit attributes are identical?
You can call getProperties() to get the persistence unit properties and compare them.
Normally EclipseLink will use the same EclipseLink ServerSession if the same persistence unit is used twice. You can call unwrap(Session.class) to get the session, and see if they are the same.
I think you're best hit would be to get (somehow, someway, ...) access to the PersistenceUnitInfo interface which is implemented and created by the container and passed to the JPA provider. The JPA provider uses it when creating the EntityManagerFactory.

EJB 3 with JDBC

Is it possible to use EJB 3 with JDBC. I read somewhere, that it's allowed.
However, I hear that EJB 3 implementation uses JTA, by default. What does that mean for JDBC? Is it only for the transaction support? That means JTA is used for transaction when using JDBC code? Meaning that even local transactions are implemented as global transactions?
Does it mean it's not a good idea to use JDBC with EJB 3? Many people point me to JPA, but it's an ORM. I want to use SQL.
any suggestions?
1º
That means JTA is used for transaction when using JDBC code ?
And
Meaning that even local transactions are implemented as global transactions ?
The EJB container CAN MAKE USE of resource manager local transactions AS AN OPTIMIZATION TECHNIQUE for enterprise beans for which distributed transactions ARE NOT NEEDED.
It is a good idea do the following when using a declarative or programmatic transaction demarcation:
declare resources using the Resource annotation in the enterprise bean class or using the resource-ref element in the enterprise bean’s deployment descriptor
Something like (setter method or member field)
// mappedName points to a global mapping name
#Resource(mappedName="java:/DefaultDS")
private javax.sql.DataSource ds;
And inside a business logic method
If you are using a declarative transaction
Connection conn = ds.getConnection();
If you are using a programmatic transaction
Declare a setter or member field UserTransaction
#Resource
private UserTransaction ut;
And
ut.beginTransaction();
Connection conn = ds.getConnection();
ut.commit();
Take care of the following
If you are using a Stateful session bean, do the following in the PrePassivate callback method
Close all JDBC connections in the PrePassivate method and assign the instance’s fields storing the connections to null
regards,
You can look at this page, it does appear that you can combine EJB3 with JDBC.
http://www.java2s.com/Tutorial/Java/0415__EJB3/UseJDBCInEJB.htm
If you are using JPA2, you can use entityManager.unwrap(Connection.class) to get actual connection and use with your JDBC code.
For example:
Connection connection = entityManager.unwrap( Connection.class );
try (Statement stmt = connection.createStatement()) {
stmt.executeUpdate( "INSERT INTO MyTable( name ) VALUES ( 'my name' ) " );
}
Does it mean it's not a good idea to use JDBC with EJB 3? Many people
point me to JPA, but it's an ORM. I want to use SQL.
Sometime it's necessary, for performance or compatibility issues. I usually use this technique to execute PL/PSQL with array parameters, complex Posgis SQL, etc.