Spring JDBCTemplate and Hibernate - spring

I have a Spring, Spring Data, JPA/Hibernate application.
The legacy part of the application uses JdbcTemplate the new stuff uses spring-data/hibernate and everything is wrapped in a transaction.
Problem is when I modify an entity via hibernate and the legacy part of the system attempts to query something that's been modified I don't get the updated values with out having to explicitly "flush" the entity manager each time.
Is it possible execute the JdbcTemplate queries against hibernate's first-level cache?
What about trying this?
Edit: https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/orm/jpa/JpaTransactionManager.html
This transaction manager also supports direct DataSource access within a transaction (i.e. plain JDBC code working with the same DataSource). This allows for mixing services which access JPA and services which use plain JDBC (without being aware of JPA)! Application code needs to stick to the same simple Connection lookup pattern as with DataSourceTransactionManager (i.e. DataSourceUtils.getConnection(javax.sql.DataSource) or going through a TransactionAwareDataSourceProxy). Note that this requires a vendor-specific JpaDialect to be configured.

Related

Mybatis and Spring data with hibernate together

We have a project which is using Spring data with hibernate as ORM.
Now we are introducing new feature for which we want to use Mybatis and eventually replace hibernate with Mybatis in all of the project but in the meanwhile can Mybatis and Hibernate live together for sometime until we make total switch. I am particularly concerned with Mybatis and Hibernate will share connection pool i.e. Hikari CP (default connection pooling that comes with spring boot, yes this project is Spring boot project!). I am not 100% sure that data source will be shared between both of them? So the question is how feasible is to have Mybatis and Hibernate together for some time ?
Honestly I never tested them together - yes both of them on its own plus JDBC, and everything worked properly - but, at first glance, there is no reason why Spring Data JPA with Hibernate and Mybatis cannot share the same connection pool and data source.
First, both frameworks can access and autodetect the same data source and underlying connection pool.
According to your comments, you are probably using Mybatis-Spring-Boot-Starter. This starter will provide you the ability to autodetect the configured data source and register a properly configured SqlSessionFactory with it.
A similar behavior of course is applicable for Spring Data JPA as well.
Moreover neither Mybatis nor Spring Data JPA should impose any restriction - number of connections, etcetera - on the underlying connection pool.
Finally, Spring Data JPA and Mybatis, this last one with the help of the companion library mybatis-spring, both support Spring's annotation-driven transaction management capability, you only need to properly define your #Transactional annotations in your methods.
Despite my recommendation would be, if possible, not to mix in the same service methods your Spring Data repositories and Mybatis mappers, I think there is no reason not to.
Spring Data Hibernate and Mybatis will be able to share the same connection pool, data source, and transaction manager.
However, there are some situations to watch out for, e.g. avoid manipulating the same object loaded by Hibernate with Mybatis.
Account account = AccountRepository.findById( 999 );
account.setAmount(111);
account.setCode(111);
// May use account to read with Mybatis
// But avoid manipulating account with Mybatis
AccountRepository.save( account );
You can get the JDBC connection from a MyBatis session using getConnection() and use it to build an Hibernate session :
sessionFactory.withOptions().connection(connection).openSession();
You can also get a reference to the underlying connection of an Hibernate Session using the doWork method:
session.doWork(new Work() {
#Override
public void execute(Connection connection) throws SQLException {

Is it a must to use spring-data-jdbc when using JdbcTemplate?

I am planning to use Spring JdbcTemplate to access my database. Is it a must to use spring-data-jdbc when using JdbcTemplate? The reason I am asking is I don't need "entity"(POJO) for my table in my application. Would it add some overheads if I use spring-data-jdbc?
You can use the JdbcTemplate without Spring Data JDBC without a problem.
JdbcTemplate existed for many years before Spring Data JDBC was conceived.
Spring Data JDBC does involve an overhead.
It extracts data from POJOs, creates queries and transforms the result back to POJOs.
Of course all that takes resources.
If you don't need/benefit from it don't use it.
You can also start with JdbcTemplate and later start using Spring Data JDBC without a problem if the need arises.
JdbcTemplate is part of the spring-jdbc module, so you only need that (and sprint-tx, which includes the DataAccessException hierarchy).
spring-data-jdbc adds support for (not surprisingly) spring-data on top of spring-jdbc. So you don't need it to use JdbcTemplate, the same as you don't need spring-data-jpa to use the JPA EntityManager.
Spring-data-jdbc is implemented on the basis of spring-jdbc. If you don't need Entity at all, then using spring-jdbc to interact directly with the database is the most convenient and flexible. In this case, using spring-data-jdbc is just a pure increase in learning costs. Spring-data-jdbc is designed for DDD (Domain Driven Design) mode, which is different from the current mainstream programming model. The learning cost is not low...

What is the point of using spring transaction while we have database level transaction?

What is the point of using spring transaction while we have database level transaction ?
If you use mysql, oracle or any other db in java, they provide methods to make things inside transaction then why spring transaction if I can do transaction using java DB driver methods ?
It's another layer of abstraction over the database transaction API. So if you wanted to use multiple databases with global transactions, Spring would allow you to do this. While I have never done it, I believe it would allow you to use DB2 and Hibernate together, for example.
Generally, what I've found is, if a feature is available in Spring, it's because there is a use case for it. They don't just put things into the framework without a reason.
Also, Spring provides declarative transaction demarcation, which produces more readable and maintainable Java code. The declarative approach lets us change the transaction strategy easily, without changing the code.
The Declarative transaction management approach allows you to manage the transaction with the help of configuration instead of hard coding in your source code. This means that you can separate transaction management from the business code. You only use annotations or XML based configuration to manage the transactions
We used Spring AOP along with Hibernate using this transaction strategy Here is an example, Spring AOP transaction mangement with Hibernate.

Spring Boot app testing with database vendor specific JPA annotation

I got an app with an existing database that has Oracle only field type (e.g. "binary-float") mapped on the entity class with #ColumnDefinition annotation.
Things runs fine when running the app normally by launching the Application class.
However I can't seem to find a way to write junit tests easily. In another Spring Boot app, I have been using different profile to define a normal datasource that points to Oracle and a junit test datasource that points to the h2 in-memory db. I stayed mostly within JPAQL and common sql standard when using direct sql. Problem is, this scheme doesn't work if the JPA mapping annotation is database specific.
Any suggestions?

SimpleJDBCTemplate and AbstractDataSource configuration

I am working on an app that uses SimpleJDBCTemplate as the wrapper to make JDBC calls.
However, instead of a conventional Datasource, I am choosing to use AbstractDataSource so I can choose from multiple data sources.
I am using ThreadLocal to inject keys to choose the appropriate Datasource.
However, it appears Spring is eagerly creating all my DAOs and my jdbcTemplate and hence I cannot figure out how to have the jdbcTemplate get Connection on demand.
Any clues.?
Do you mean AbstractRoutingDataSource? If not, you really should be using that, since this is exactly what it's for. Mark Fisher wrote a useful blog about it back when it was added to the framework.
Yes Spring will create your DAOs and JdbcTemplates eagerly if they're singletons, which is the default, but that doesn't mean they all obtain a connection immediately. A connection will only be obtained when you start some kind of operation that uses that data source. Typically, that would be starting a transaction. In other words, what you say you want to happen is what already happens.

Resources