Lucee Hibernate extension doesn't support long-lived session

Description

The Lucee Hibernate extension (both 3.5 and 5.4) expect the session to be closed at the end of each transaction. (See https://luceeserver.atlassian.net/browse/LDEV-4017.) If the Lucee Hibernate transaction wrapper does not close the session, future transactions in the same request will cause a “Transaction already active” error.

See stack trace:

Errored: Transaction already active [java] [script] /home/me/lucee/lucee/test/orm/many2many/index.cfm:61 [java] [script] /home/me/lucee/lucee/test/orm/Hibernate.cfc:67 [java] [script] /home/me/lucee/lucee/test/_testRunner.cfc:370 [java] [script] /home/me/lucee/lucee/test/run-tests.cfm:203 [java] [script] /bootstrap-tests.cfm:108 [java] [script] [java] [script] [java] [script] lucee.runtime.exp.NativeException: Transaction already active [java] [script] at org.hibernate.engine.transaction.internal.TransactionImpl.begin(TransactionImpl.java:74) [java] [script] at org.hibernate.internal.AbstractSharedSessionContract.beginTransaction(AbstractSharedSessionContract.java:480) [java] [script] at org.lucee.extension.orm.hibernate.HibernateORMTransaction.begin(HibernateORMTransaction.java:30) [java] [script] at lucee.runtime.orm.ORMConnection.<init>(ORMConnection.java:66) [java] [script] at lucee.runtime.orm.ORMDatasourceConnection.<init>(ORMDatasourceConnection.java:76) [java] [script] at lucee.runtime.db.DatasourceManagerImpl._add(DatasourceManagerImpl.java:163) [java] [script] at lucee.runtime.db.DatasourceManagerImpl.add(DatasourceManagerImpl.java:149) [java] [script] at lucee.runtime.PageContextImpl.getORMSession(PageContextImpl.java:3503) [java] [script] at lucee.runtime.orm.ORMUtil.getSession(ORMUtil.java:58) [java] [script] at lucee.runtime.orm.ORMUtil.getSession(ORMUtil.java:54) [java] [script] at lucee.runtime.functions.orm.EntitySave.call(EntitySave.java:33) [java] [script] at lucee.runtime.functions.orm.EntitySave.call(EntitySave.java:29) [java] [script] at orm.many2many.index_cfm$cf.call(/test/orm/many2many/index.cfm:61) [java] [script] at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:1049) [java] [script] at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:941) [java] [script] at lucee.runtime.listener.ModernAppListener._onRequest(ModernAppListener.java:221) [java] [script] at lucee.runtime.listener.MixedAppListener.onRequest(MixedAppListener.java:45) [java] [script] at lucee.runtime.PageContextImpl.execute(PageContextImpl.java:2485) [java] [script] at lucee.runtime.PageContextImpl._execute(PageContextImpl.java:2471) [java] [script] at lucee.runtime.PageContextImpl.executeCFML(PageContextImpl.java:2442) [java] [script] at lucee.runtime.functions.system.InternalRequest.call(InternalRequest.java:135) [java] [script] at orm.hibernate_cfc$cf.udfCall1(/test/orm/Hibernate.cfc:67)

Environment

Lucee 6.0.0.211 with Hibernate 5.4 extension or Hibernate 3.5.5 extension.

Also Lucee 5.3.10.32-SNAPSHOT with Hibernate 5.4 extension.

Activity

Pothys - MitrahSoft 
24 August 2022 at 10:01

I closed the ticket as mentioned by the

Michael Born @ Ortus 
28 July 2022 at 16:04

I would recommend closing this ticket. It is a mere implementation detail on https://luceeserver.atlassian.net/browse/LDEV-4017, meaning that to fix 4017 will require fixing a number of assumptions in the Hibernate ORM session management and possibly connection management.

Michael Born @ Ortus 
28 July 2022 at 13:09
(edited)

There appear to be two separate issues here:

  1. A new ORM connection is created at some point in the middle of a request. (at lucee.runtime.orm.ORMDatasourceConnection.<init>(ORMDatasourceConnection.java:76)) Why? This seems concerning, if you ask me. Why would an entitySave() run a code path that opens a brand new ORM connection? Is the current connection invalid? Released?

  2. Opening a new ORM connection causes a transaction to be created even if one exists already. See https://github.com/lucee/Lucee/blob/f438389b2777542f560bcbb85d8dcd41eae7df21/core/src/main/java/lucee/runtime/orm/ORMConnection.java#L65-L66 . calling session.getTransaction().begin() will create a new transaction, period. Hibernate documentation recommends session.beginTransaction() instead, as that will check for an existing (active) transaction and return that if found.

UPDATE: I realized this is calling the Hibernate extension (not calling Hibernate directly). So #2 is not a valid point - the Hibernate extension is properly creating the transaction, although it seems Hibernate is failing to detect and return an existing transaction like the docs claim it should.

Closed

Details

Assignee

Reporter

Priority

New Issue warning screen

Before you create a new Issue, please post to the mailing list first https://dev.lucee.org

Once the issue has been verified, one of the Lucee team will ask you to file an issue

Created 28 July 2022 at 13:00
Updated 24 August 2022 at 10:01
Resolved 24 August 2022 at 10:01