R2DBC vs Spring Jdbc Vs Spring Data JDBC? - spring

On Using Spring JDBC which works very well and has some improvements over JPA when using Batch processing.
I would love to learn why to use Spring Data JDBC when you already have Spring JDBC.
I would love to learn why to use R2DBC when you already have Spring JDBC.

The three technologies work on different abstraction levels.
R2DBC is an alternative to JDBC. It is reactive, i.e. non-blocking. You send a statement to the server, continue to work and eventually receive the results as an event. It is often used for the ability to better scale. But using it is more complex because it is asynchronous and basically your complete application should be too in order to get the benefits. As with JDBC you probably don't want to use it on its own.
Spring JDBC is comparable to Spring R2DBC both hide some of the more tedious details of the underlying technology. They both offer pretty much full access to the underlying technology and just give you a more pleasant developer experience.
Spring Data JDBC is an Object Relational Mapper (ORM) based on the Repository abstraction. For the reactive world there is also Spring Data R2DBC which shares code and properties with Spring Data JDBC. It is basically a replacement of Spring Data JPA. For a comparison of Spring Data JDBC and Spring Data JPA see https://stackoverflow.com/a/42488593/66686.
The Repository abstraction of Spring Data comes from Domain Driven Design. You can think of a Repository as a collection that is backed by some persistence mechanism. The elements of that collections are not just entities but aggregates, which belong together and don't make sense on their own. A typical example is a Purchase Order with its Line Items. A Line Item doesn't make much sense without its Purchase Order.
This approach puts some constraints on the design of your domain model. In return you get a nice clean structure for you domain model. Both Spring Data JDBC and Spring Data R2DBC allow to combine them freely with Spring JDBC and Spring R2DBC. This is very different for JPA and everything build on it, because JPA has a cache as integral part of the system which will lead to interesting effects when you mix JPA and direct JDBC access within a single transaction.
See the following table for an overview of the different technologies discussed.
Stack
JDBC to Spring Data JDBC
R2DBC to Spring Data R2DBC
JDBC to Spring Data JPA
Underlying API
JDBC
R2DBC
JDBC
Usability Layer
Spring JDBC
Spring R2DBC
Spring ORM (*)
ORM
Spring Data JDBC
Spring Data R2DBC
JPA
Repository Abstraction
Spring Data JDBC
Spring Data R2DBC
Spring Data JPA
Communication Style
synchronous
reactive
synchronous
(*) Spring ORM sits on top of JPA or other Spring independent ORM technologies, so in this table it kinda should be below JPA.

When you would use R2DBC is easy, it’s when you are building an application that is non-blocking. Everything in the stack has to be non-blocking, including the database driver. JDBC is inherently blocking, people try schemes to get around it but it is not great. If you aren’t building a non-blocking application you wouldn’t use R2DBC.
For the part about when to use spring data JDBC, it looks like it gives you a simpler way to create repositories and map data, as long as you’re ok with their opinionated framework, you are ok with not having all the complex mappings you get with JPA, and you want the DDD concepts (like aggregate root). Otherwise Spring JDBC requires more code to create your data access objects but may give more control. https://docs.spring.io/spring-data/jdbc/docs/2.2.4/reference/html/#reference describes more about why to use Spring Data JDBC. It is simplicity vs control.

Related

Can we use hibernate with spring web flux

I am new to reactive programming I have started using webflux, previously I work on spring boot there I have used hibernate as a ORM framework. My doubt is what is replace of hibernate in reactive stack , which framework I have to use to connect & implement database logic.
I am using mongoDB.
Thanks in advance.
you have to use either R2DBC or Hibernate reactive.
if you migrating an old service from spring boot to webflux, I recommended you to use Hibernate reactive.
when you use R2DBC, you can't use hibernate mappings and annotations.
according to hibernate reactive documentation:
When using a stateless session, you should be aware of the following additional limitations:
persistence operations never cascade to associated instances,
changes to #ManyToMany associations and #ElementCollections cannot be
made persistent, and
operations performed via a stateless session bypass callbacks.
Hibernate is based on JDBC. JDBC is blocking. Blocking APIs don't work well in reactive stacks. Also, Hibernate under the hood uses ThreadLocals which makes it even worse candidate for reactive applications.
For Webflux, as the alternative to Hibernate you should look into Spring Data R2DBC which does the basic database result to Java object mapping, but keep in mind that it's not a full fledge ORM like Hibernate.
You may also want to give it a try to Hibernate Reactive. With this you can use the power of Hibernate mappings in a reactive non blocking way. One thing that will not work though (at least not yet) is declarative transaction management with #Transactional.
It depends on what database driver you are using.
If using the jdbc driver to talk to your database, then yes you can use hibernate. But important to note is that the JDBC spec is blocking so every call to the database will be blocking, and must be placed on its own scheduler (thread) and you will most likely not get the full performance benefits of a fully reactive application.
If you want a fully reactive application you must use a database driver that supports the R2DBC protocol. Hibernate does not support R2DBC so can not be used if you want a fully reactive application.
Hibernate is most commonly used with relation database such as mysql, postgres, oracle etc and not NoSql databases such as monogDB.
If you are using MongoDB then there is full support for R2DBC and there is no need for hibernate.

How to use Spring transactions with plain old jdbc connection without Spring jdbc template?

We have an old EJB based web application which we are supposed to migrate into Spring boot. For database connectivity, it is a plain old jdbc connection approach as of now.
We want to use Spring transactions and remove EJB transactions but willing to keep plain old jdbc connectivity same. In short we don't want to make changes in our DAO layer to convert plain old jdbc to Spring JdbcTemplate.
Please note that we have our own connection pooling algorithm and we create connection object and close it in the pool.
Along with this we want our application to be multi-tenant that can work with multiple databases on the basis of 'tenantID' that we will provide.
I actually tried to implement this but it is not working. I had to manually do con.commit(); and con.rollback();
Is there any way to use Spring transactions with plain old jdbc connectivity with above scenario?

Spring Transaction Management usage

Can anybody provide me an example for Spring Transaction management? I have queries like how it basically works? In Java EE , Application server container used to take care of the transaction using EJB's. I wanted to know ,how spring frameworks helps in the same way?
I hope Introduction to Spring Framework transaction management will help.
The Spring Framework’s transaction management support doesn't requires an application server.
Spring Frameworks Claims declarative transactions of spring framework offer more powerful and more productive programming model than EJB CMT.
Compared to transaction management using EJB Spring frameworks enables application developers to use a consistent programming model in any environment. Once we write our code once it can benefit from different transaction management strategies in different environments.
The Spring Framework provides both declarative and programmatic transaction management.
programmatic transaction management - developers work with the Spring Framework transaction abstraction, which can run over any underlying transaction infrastructure.
declarative model - developers typically write little or no code related to transaction management, and hence do not depend on the Spring Framework transaction API, or any other transaction API.
Spring framework provides central interface for transaction
management i.e. 'PlatformTransactionManager'
There are many implementations if it, one which you can quickly
relate to is DataSourceTransactionManager.
Now, this transaction manager does the lower level work of beginning,
rollback and commit of transaction for you.
If you see the source of DataSourceTransactionManager you will see
the same kind of transaction management code that you have seen when
you handle transaction using JDBC api
But importantly, all these things happen declaratively as part of
proxy advise using Spring AOP
Begin Transaction
DataSource ds = /*initialize DS here*/
Connection con = ds.getConnection();
con.setAutoCommit(false);
Commit Transaction
com.commit();

Spring JTA supported by MONGODB

In my application I need to store some data to the RDBMS DB and some data to the MongoDB in the same transaction and I am using Spring JTA for my RDBMS transactions.
I am new to MongoDB and i am not sure that will this Spring JTA supported by MongoDB. What's the way or api to handle a transaction programmaticaly in MongoDB as MongoDB doesn't support transaction.
As like working with RDBMS and by annotating a method #Transactional, all operation's in method done as a single atomic operations and if an error occur automatic rollback done by Spring JTA but how we can achieve this using MongoDB?
You can use atomic operations or two-phase commit. Also Check this out. This article explains about plugin developed for Mongo that promises not only transactions but also a boosting in performance.

Sharing JMS and Hibernate transactions in a Spring MDB using Oracle Streams AQ?

I'm using Oracle 11g for my database and its Oracle Streams AQ feature as JMS implementation.
For all I know, it should be possible to implement a Spring based message-driven POJO (MDP) that uses the same data source for both transactional data access and JMS transactions -- all without XA-Transactions (IIRC, this was marketed as a feature of SpringSource Advanced Pack for Oracle).
Is this possible using Hibernate as well? Ideally, my MDP would start a JMS transaction and read a message from a queue, then re-use the transaction for data access through Hibernate. If anything goes wrong, the JMS and database transaction would both be rolled back, without using 2-phase commit (2PC).
I'm not much of a transaction guru, so before I start digging deeper, can anyone confirm that this is possible and makes sense as well?
Update:
What I want is an implementation of the Shared Transaction Resource pattern. The sample code demonstrates it for ActiveMQ and JDBC, but I need to use Oracle Streams AQ and Hibernate.
Update2:
The SpringSource Advanced Pack for Oracle has been open sourced as part of Spring Data JDBC and it "provides the option of using a single local transaction manager for both
database and message access without resorting to expensive distributed 2-phase commit
transaction management".
2PC shouldn't be necessary, as you say, since the appserver should take care of it. However, you'll pretty much have to use JTA (i.e. JavaEE container) transactions, rather than vanilla DataSource transactions, since JMS only works with JTA.
This isn't a big deal, it's just a bit more fiddly:
Your Spring config should use
<jee:jndi-lookup/> to get a
reference to your container's
DataSource, and you inject that
data source into your spring-managed
hibernate SessionFactory.
You then need to introduce a transaction manager into the context (<tx:jta-transaction-manager/> should work in most app-servers).
In your Spring JMS MessageListenerContainer, plug the above transaction manager reference into it.
Does that all make sense, or should I elaborate? This setup should ensure that the container-managed transactions are held across JMS and Hibernate interactions.

Resources