Description
Hibernate doesn't seem to work using TransactionalRequest
in 3.5.3 with enabledDefault = false and @Transactional
annotation:
TransactionalRequest apply has this code:
...
try (var session = sessionProvider.create(ctx, sessionFactory)) {
io.jooby.internal.hibernate.RequestSessionFactory.StatefulSessionFactory
provides this create
method, which is called:
public SharedSessionContract create(Context ctx, SessionFactory sessionFactory) {
var sessionProvider = ctx.require(sessionProviderKey);
var session = sessionProvider.newSession(sessionFactory.withOptions());
return ManagedSessionContext.bind(session);
}
org.hibernate.context.internal.ManagedSessionContext
bind
is implemented as:
public static Session bind(Session session) {
return (Session)sessionMap(true).put(session.getSessionFactory(), session);
}
sessionMap will return a HashMap
, and put
in HashMap
calls putVal
(though that may be JDK dependent - latest temurin JDK 21 in my case) which will return the PREVIOUS value of that key, or null, if there was no previous value. The spec also seems to support this behavior, so basically all JDKs should behave this way.
So the code will result in an NPE, once TransactionalRequest
tries to call anything on session - like it does in the apply method (the same I mentioned at the top):
trx = session.getTransaction();
I think it would be correct to fix ManagedSessionContext
to return the new session, and not the previous value, OR in StatefulSessionFactory
return the session, instead of the previous session, or ...
Note that this has probably been broken for some time already, as I couldn't find a recent commit that changed the code and we upgraded from 3.1.1 to 3.5.3 and I didn't want to go through hundreds of commits, as bisecting didn't yield anything meaningful