I'm using Spring + Spring Data JPA with Hibernate and I need to perform some large and expensive database operations.
How I can use a StatelessSession
to perform these kind of operations?
You cant actually use both of them in the same application.
A stateless session does not implement a first-level cache nor interact with any second-level cache, nor does it implement transactional write-behind or automatic dirty checking, nor do operations cascade to associated instances. Collections are ignored by a stateless session.
JPA cannot deal with reactive repositories such as provided by Spring Data R2DBC. This means you will have to do more things manually when using R2DBC. There are other reactive drivers around such as for example Quarkus Reactive Postgres client (which uses Vert.
To get even better performance results you can enable jdbc batch statements on the SessionFactory
/ EntityManager
by setting the hibernate.jdbc.batch_size
property on the SessionFactory configuration (i.e.: LocalEntityManagerFactoryBean
).
To have an optimal benefit of the jdbc batch insert / updates write as much entities of the same type as possible. Hibernate will detect when you write another entity type and flushes the batch automatically even when it has not reached the configured batch size.
Using the StatelessSession behaves basically the same as using something like Spring's JdbcTemplate
. The benefit of using the StatelessSession
is that the mapping and translation to SQL is handled by Hibernate. When you use my StatelessSessionFactoryBean
you can even mix the Session
and the StatelessSession
mixed in one transaction. But be careful of modifying an Entity loaded by the Session
and persisting it with the StatelessSession
because it will result into locking problems.
A solution is to implement a Spring factory bean to create this StatelessSession
and inject it in your custom repositories implementation:
public class MyRepositoryImpl implements MyRepositoryCustom {
@Autowired
private StatelessSession statelessSession;
@Override
@Transactional
public void myBatchStatements() {
Criteria c = statelessSession.createCriteria(User.class);
ScrollableResults itemCursor = c.scroll();
while (itemCursor.next()) {
myUpdate((User) itemCursor.get(0));
}
itemCursor.close();
return true;
}
}
Check out the StatelessSessionFactoryBean
and the full Gist here. Using Spring 3.2.2, Spring Data JPA 1.2.0 and Hibernate 4.1.9.
Thanks to this JIRA and the guy who attached StatelessSessionFactoryBean
code. Hope this helps somebody, it worked like a charm for me.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With