As I understand so far stateless sessions are preferred when using batch processes since It will just detach objects doing the process So that persistent context and cache would be free so batch processes are the idle case for that, It is commonly known as plain JDBC Query Engine with queries translated to SQL queries immediately. Referenced from : https://stackoverflow.com/a/14174403/1460591
On the other hand, I learned that native queries do the same the one difference I see is that the stateless session can map the result to an entity, Native queries don't do that until mapper is explicitly provided.
So is there another difference and from a performance point of view which is better when doing batch processes?
3 Answers
Answers 1
If by batch processing you mean modifying entities in the database server via the SQL query itself (e.g. UPDATE things SET daily_quota=15
) then the native SQL is faster. However, in this case, you aren't loading any entities so this doesn't really seem to jive with your question.
If by batch processing you mean modifying entities in your program (e.g. load all Thing
instances, modify the dailyQuota
attribute to 15
and write an update then you will want a stateless session.
Using a native query to retrieve the objects doesn't give you any mechanism to modify the object. You still need to merge it back to the persistence context and flush those changes. Once you do this (assuming you don't have a stateless session) then it will use the classic change-detecting & cache-keeping flush mechanism.
A stateless session on the other hand gives you a way to modify entities in your program without forcing the ORM layer to go through the slow change detection process.
Answers 2
As always, if it comes to performance, the best thing to do is to measure. Noone can tell which one will be better in your setup, we don't know which DB you are using, which Hibernate version, which OS, etc. Depends on a lot of things.
However, if it comes to performance, the best thing you can do is using native queries. If you can simply put your update logic into a query, do it and execute the query. In this case the DB will handle everything which is the best in terms of performance.
If it's a requirement for you to work with entities, go with stateless session because as you mentioned it gives you the possibility to map the results of a query to entities. Although, there are other differences between going stateless and native queries:
With stateless session you will lose:
- First level caching
- Second level caching
- Any interceptor mechanism, as it's bypassing everything
- Automatic dirty checking
- Cascading
Of course losing these also means performance, but if any of these are important for you, it's better to avoid then.
In case you want to go with a regular session, you can use JDBC batching as well which greatly can improve the performance, but make sure you regularly flush and clear your persistence context to avoid growing your cache.
Answers 3
Hello before crashing into the Hibernate Stateless session I would seriously ask myself why do I need it. First you already got the idea and the features you will loose when using Stateless session.
Even though the hibernate session is memory consuming you can still get decent performance in most cases speed. If you can not do that probably you have other problems in your code.
I would like to emphasize that the stateless session does not cascade the persist, merge and so on.. operations. This will remove a significant element of the authomatization you would normaly recieve through hibernate. This may affect your code in long run in terms of maintanability and the ease of change.
Since no code is completly static in terms of development, new features are coming sometimes something needs to be changes and so on.... very often a simple at a first glance batch may turn into something pretty big. In which case the amount of features you have at hand really matters.
I would argue that if you realy are in desparate need of performance then you should have a clear separation of the persistence from tghe business layer in terms of repositorys or something else. And if nessesary you just write some pure SQL based repositories or something that is as close as possible to native sql for example JOOQL.
During my career I have seen some pretty complex batches written with normal hibernate session running quite OK when the SLA is taken in mind. I have a resent example of a batch running over 2000 distributed transactions per second over 16 cpus writen with Hibernate with normal session.
The very few cases where I need massive performance I would just use JOQL because it is the closest thing to SQL which maintains ORM relations.
0 comments:
Post a Comment