hibernate-reactive: IllegalStateException: HR000069: Detected use of the reactive Session from a different Thread

During development of my Vert.x Hibernate Reactive PoC in encountered the following error:

java.util.concurrent.CompletionException: javax.persistence.PersistenceException: org.hibernate.HibernateException: java.lang.IllegalStateException: HR000069: Detected use of the reactive Session from a different Thread than the one which was used to open the reactive Session - this suggests an invalid integration; original thread: 'vert.x-eventloop-thread-8' current Thread: 'vert.x-eventloop-thread-0'

I have written a reproducer and can also give the following information:

  • The issue does not happen when using Vert.x 4.1.5 - I was only able to reproduce it when using 4.2.1 (I did not test other versions). I thus assume it might be a regression related to the Vert.x code or Vert.x dependencies.
  • Even while using Vert.x 4.2.1 I was not seeing this issue when using the a mutiny variant of the example.
  • When not sharing the SessionFactory across verticles the error does not happen.

Steps to reproduce

  1. git clone https://github.com/Jotschi/hibernate-reactive-howto.git
  2. checkout rxjava3-shared-emf
  3. Start MainVerticleStage
  4. Invoke wrk -d 10s -c 20 http://localhost:8080/products to utilize the REST API
  5. Observe the IllegalStateException in the logs

Log

https://gist.github.com/Jotschi/4fe6263369be82871fb958816400f1e1

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 18 (12 by maintainers)

Most upvoted comments

@DavideD Yep, thats basically the way I have fixed it now. I have to check my examples and make sure that all the sections are correct. I don’t want to promote the wrong way of initializing hibernate reactive.

Yes, the executeBlocking approach works as well. Basically, there are multiple ways to do the same thing. Just keep in mind that it will create a different factory for each Verticle instance. You could also do something like this:

Uni<Mutiny.SessionFactory> startHibernate = Uni.createFrom().deferred( () -> Uni
				.createFrom().item( createHibernateSessionFactory().unwrap( Mutiny.SessionFactory.class ) ) );

vertx
	.executeBlocking( startHibernate )
	.chain( msf -> vertx.deployVerticle( () -> new MainVerticle( msf ), options ) )
	.subscribe().with(
		d -> {
			LOG.info( "✅ Deployment success" );
			LOG.info( "💡 Vert.x app started" );
		},
		err -> LOG.error( "🔥 Deployment failure", err )
	);

I think the issue can be closed. I personally would not mind if this situation would cause an exception. (e.g. … must be invoked within a Vert.x context).

I wouldn’t force it. It seems a valid approach to create a factory and then pass it to a verticle. Plus, some people might want to use HIbernate Reactive without dealing with Vert.x directly. In that case they wouldn’t have an instance of Vert.x.