0

I am currently trying to learn about the hibernate sessions. So, I am trying to process run some processes using CompletableFuture in java. The function inside the supplyAsync() has some DB processes to run. Earlier, I was running into no session currently bound to execution context even when I added @UnitOfWork to my resource.

In order to solve the issue, now I am currently opening and closing the session within the DAO's method findAll(). Since, the codebase is very big, I am going to only add a file which can illustrate the concern.

Main.java

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class Supply {

    public static void main(String... args) throws ExecutionException, InterruptedException {
      final CompletableFuture<Integer> future = CompletableFuture
          .supplyAsync(() -> doSomethingAndReturnA())
          .thenApply(a -> convertToB(a));

      System.out.println(future.get());
    }

    private static int convertToB(final String a) {
      System.out.println("convertToB: " + Thread.currentThread().getName());
      return Integer.parseInt(a);
    }

    private static String doSomethingAndReturnA() {
      System.out.println("doSomethingAndReturnA: " + Thread.currentThread().getName());
      try {
        // some DB processes
        List<String> list = someDAO.findAll(); // opening and closing session in findAll()
        Thread.sleep(1000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }

      return "1";
    }
}

public List<String> findAll() throws Exception{
        List<String> temp = null;
        Session session = sessionFactory.openSession();
        LOGGER.debug("Opened the session");
        try {
            ManagedSessionContext.bind(session);
            Transaction transaction = session.beginTransaction();
                try {
                    temp = list((Query<String>) namedQuery("something.findAll"));
                    transaction.commit();
                }
                catch (Exception e) {
                    transaction.rollback();
                    throw new Exception(e.getMessage());
                }
        } finally {
            session.close();
            ManagedSessionContext.unbind(sessionFactory);
        }
        return temp;
    }
  1. Since, I added @UnitOfWork in my resource file where I am calling my doSomethingAndReturnA() directly, do I need to worry about separate sessions which are going to be opened in findAll().

  2. I also read that I can access getCurrentSession() which will only create a session if it doesn't exists but for that I need a hibernate.cfg.xml and add current_session_context_class. Is there a way to write that file?

Of the two methods getCurrentSession() vs opening and closing sessions, which is more efficient and scalable.

harry123
  • 760
  • 1
  • 7
  • 22
  • 1
    Note: Hibernate `Session` is deprecated. The standard JPA `EntityManager` API is now recommended. – chrylis -cautiouslyoptimistic- Jun 25 '21 at 05:03
  • @chrylis-cautiouslyoptimistic- I do not see that [Session](https://docs.jboss.org/hibernate/orm/5.5/javadocs/org/hibernate/Session.html) is deprecated now. It's just extends the JPA `EntityManager` interface now. But it also provides some hibernate specific features. – SternK Jun 25 '21 at 06:50
  • Does this answer your question? [Suitable way to interact with Hibernate sessions in multi-thread environment](https://stackoverflow.com/questions/50630776/suitable-way-to-interact-with-hibernate-sessions-in-multi-thread-environment) – SternK Jun 25 '21 at 07:23
  • @SternK Thank you for the reply but that post also tells the difference between the two. With `openSession()` I will have to maintain the session. My concern is what would happen if I call `doSomethingAndReturnA()` directly and multiple times. That will be opening multiple sessions. Will that impact the efficiency? I am using dropwizard BTW – harry123 Jun 25 '21 at 14:12
  • I am not sure if opening multiple sessions on the main thread is recommended. – harry123 Jun 25 '21 at 14:27
  • 1. It's hard to say something without looking at the `someDAO.findAll()` implementation. 2. As `Session` is not thread-safe, you can not use it in the multi-thread environment, only conjunction `hibernate.current_session_context_class=thread` and `sessionFactory.getCurrentSession();` in current thread make usage thread-safe (assuming that this is plain java+hibernate app without spring or another DI container) – SternK Jun 25 '21 at 14:31
  • @SternK I updated/added `findAll` example, if that helps. – harry123 Jun 25 '21 at 17:17

0 Answers0