You can initialize a singleton SessionFactory. It is really recommended.
Then, each thread must create a session using the factory session and complete the transaction (s).
This is really a very common pattern used in web applications. The Open Session in View template that @kvista mentions is basically a servlet filter that creates a session, starts a transaction, delegates everything that continues processing the request, and completes or rolls back the transaction at the end. And since each request is processed by a different thread in the servlet container, you can see how close the two cases are.
In your case, it would be unreasonable to execute many transactions in each thread. In fact, this is the main idea of executing batch processes in a multi-threaded (ideally JTA) environment. However, one thing you should note is that a session is actually a persistence context that acts like a cache, and you should probably flush it from time to time to avoid memory leaks.
source share