1

I am using simple-react.

Inside LazyFutureStream I want to persist the entity .

LazyFutureStream.parallel(1,2,3,4,5)
       .map(id -> {
            try {
                SessionFactory sessionFactory = Application.getHibernateBundle()
                                                           .getSessionFactory();
                ManagedSessionContext.bind(sessionFactory.openSession());
                Session session = sessionFactory.getCurrentSession();
                session.beginTransaction();

                Model model = new Model(sessionFactory);
                model.persist(id);
                session.getTransaction().commit();
            }
        });

Is this correct ? Is there any way i can skip session factory creation for every thread .

ALSO in above I only want to fork but not join. Is that fine?

Cœur
  • 37,241
  • 25
  • 195
  • 267
T.J.
  • 1,466
  • 3
  • 19
  • 35
  • 2
    No, this is not correct. Your `try` block lacks a `catch` or `finally`. Besides that, `map` operations are usually supposed to *map* from one item/value to another, hence the associated function must return a value. If you just want to consume items, `forEach` may be the way to go. And if you don’t want to create a new Session for each item, move its creation code out of the lambda expression. – Holger Sep 15 '15 at 12:56
  • if i move the Session out , then it will be shared one, Will that lead to some issues regarding thread concurrency – T.J. Sep 15 '15 at 13:11
  • 1
    I don’t know enough about hibernate to say something about thread safety of the `Session` class. But in case it’s not, you can always wrap a supplier of a non thread safe component into a `ThreadLocal`. That way, you are safe having one per thread, but still skip the creation for items processed by the same worker thread. But maybe someone will come up with a definite answer regarding the thread safety of a `Session`. In the meanwhile, you could try searching for an answer in its documentation… – Holger Sep 15 '15 at 13:17
  • You mean is that threadLocal.set(session) will make the session object exclusive to it . similar for all other thread , . Same session object will be replicated for each thread if set on thread local – T.J. Sep 15 '15 at 13:45

1 Answers1

1

I'm the author of simple-react, while I'm definitely not an expert on Hibernate's SessionFactory, these Stackoverflow posts does suggest it is safe to share them across threads however.

Optimizing your Stream

LazyFutureStream.parallel uses the Common ForkJoinPool (the same as standard Java 8 parallel Streams). So, if you are using these elsewhere in your application (particularly for CPU Bound tasks), they will compete with your blocking I/O.

LazyReact StreamBuilder

You can use the LazyReact Stream Builder to set up a Stream builder that uses a custom thread pool (and do resuse the builder, the JVM doesn't do a great job of Garbage Collecting Thread pools).

To setup a Stream builder with a thread pool of 10 threads, and that allows 10 active Futures -

    LazyReact streamBuilder = new LazyReact(10,10);

Creating your stream

As Holger suggested you can use forEach (this is efficient on simple-react v0.99.x and above, on previous versions a peek / run combo will perform better)

   streamBuilder.of(1,2,3,4,5)
                 .forEach(id-> { //do work here });

This will execute on your thread pool, but will block the current thread until the work completes.

For a non-blocking alternative you can use run() with peek.

   streamBuilder.of(1,2,3,4,5)
                 .peek(id-> { //do work here })
                 .run();
Community
  • 1
  • 1
John McClean
  • 5,225
  • 1
  • 22
  • 30