Possible ORM Transaction bug in lucee-4.5.1.000

I’ve stumbled onto some strange behavior in Lucee while working through
examples in the ColdFusion ORM book by John Whish.

Specifically, many of the updates and deletes I’m attempting within a
transaction{} are failing to persist to the database (MySQL) - some of them
resulting in lengthy hibernate stack trace exception messages. This may be
related to this reported
issue: https://bitbucket.org/lucee/lucee/issue/77/orm-doesnt-persist-data-in-cftransactions

Here are a couple of videos demonstrating a couple of scenarios where this
is occurring:

http://screencast.com/t/wJNUvuNi9r

http://screencast.com/t/y3dd9sNbsHS

Orm settings in Application.cfc:

this.ormenabled = true;
this.ormsettings.dbcreate = “update”;
this.ormsettings.flushAtRequestEnd = false;

First video’s template that fails:

transaction {
// get category 1
MyCategoryA = entityLoadByPK(“Category”, 1);
MyCategoryA.setTitle(“testme”);

// do some validation
if (MyCategoryA.getTitle() == “”) {
transaction action=“rollback”;
}
}

transaction {
// get category 2
MyCategoryB = entityLoadByPK(“Category”, 2);
MyCategoryB.setTitle(“some other new title”);

// do some validation
if (MyCategoryB.getTitle() == “”) {
transaction action=“rollback”;
}
}

writeOutput(“done!”)

Second video template that fails:

transaction {
newCatTitle = “What You talking about, Willis?”;
MyCategory = EntityNew(“Category”);
MyCategory.setTitle(newCatTitle);
EntitySave(MyCategory);

}

writeOutput(“category #newCatTitle# Added!”);

There are similar problems with using entityNew() and entityDelete() within
a transaction{} block.

Thanks for all you guys do!

cheers,
-sutton

Nando,

When I try that following an EntityNew() call within the transaction block
(below), interestingly, the error/exception message goes away. However,
the data is not persisting to the database.

transaction {
newCatTitle = “New Category from addcategory3.cfm”;
MyCategory = EntityNew(“Category”);
MyCategory.setTitle(newCatTitle);
if (MyCategory.getTitle() == “”) {
transaction action=“rollback”;
} else {
transaction action=“commit”;
}
}

Another interesting point: The problem/error does not occur when
calling entityLoadByPK() or entityLoad() within a single transaction{}
block. The following code works as expected (with or without the
transaction action=“commit” statement:

transaction {
// get category 1
MyCategoryA = entityLoadByPK(“Category”, 1);
MyCategoryA.setTitle(“yoyo”);

// do some validation
if (MyCategoryA.getTitle() == “”) {
transaction action=“rollback”;
}
}

That said, if I had a second transaction block the same request, the second
transaction will fail every time in all cases I’ve tested so far.

Thanks!
-suttonOn Wednesday, March 18, 2015 at 3:47:09 PM UTC-4, Sutton Yamanashi wrote:

I’ve stumbled onto some strange behavior in Lucee while working through
examples in the ColdFusion ORM book by John Whish.

Specifically, many of the updates and deletes I’m attempting within a
transaction{} are failing to persist to the database (MySQL) - some of them
resulting in lengthy hibernate stack trace exception messages. This may be
related to this reported issue:
https://bitbucket.org/lucee/lucee/issue/77/orm-doesnt-persist-data-in-cftransactions

Here are a couple of videos demonstrating a couple of scenarios where this
is occurring:

http://screencast.com/t/wJNUvuNi9r

http://screencast.com/t/y3dd9sNbsHS

Orm settings in Application.cfc:

this.ormenabled = true;
this.ormsettings.dbcreate = “update”;
this.ormsettings.flushAtRequestEnd = false;

First video’s template that fails:

transaction {
// get category 1
MyCategoryA = entityLoadByPK(“Category”, 1);
MyCategoryA.setTitle(“testme”);

// do some validation
if (MyCategoryA.getTitle() == “”) {
transaction action=“rollback”;
}
}

transaction {
// get category 2
MyCategoryB = entityLoadByPK(“Category”, 2);
MyCategoryB.setTitle(“some other new title”);

// do some validation
if (MyCategoryB.getTitle() == “”) {
transaction action=“rollback”;
}
}

writeOutput(“done!”)

Second video template that fails:

transaction {
newCatTitle = “What You talking about, Willis?”;
MyCategory = EntityNew(“Category”);
MyCategory.setTitle(newCatTitle);
EntitySave(MyCategory);

}

writeOutput(“category #newCatTitle# Added!”);

There are similar problems with using entityNew() and entityDelete()
within a transaction{} block.

Thanks for all you guys do!

cheers,
-sutton

I think what you’re seeing is related to issue #77 as you say.

I notice you’re comparing with Railo 4.2.1.008, the final stable
release, where the ORM transactions work ok. A patch introduced in the
Railo 4.2.2 preview release caused ORM transactions to start
failing. For more detail see:

http://cfsimplicity.com/93/migrating-from-coldfusion-to-railo-part-6-more-orm-issues

Unfortunately Lucee was forked from that preview release rather than
the stable one, although I’ve found the problems do appear to have
been partially mitigated:

http://cfsimplicity.com/98/migrating-from-coldfusion-to-railo-to-lucee

Wherever you have transactions failing to persist changes, try adding
OrmFlush() at the end. It should not be necessary, but I’m not
optimistic this will be fixed in the short term.

Julian.On 18 March 2015 at 19:47, Sutton Yamanashi <@Sutton_Yamanashi> wrote:

I’ve stumbled onto some strange behavior in Lucee while working through
examples in the ColdFusion ORM book by John Whish.

Specifically, many of the updates and deletes I’m attempting within a
transaction{} are failing to persist to the database (MySQL) - some of them
resulting in lengthy hibernate stack trace exception messages. This may be
related to this reported issue:
https://bitbucket.org/lucee/lucee/issue/77/orm-doesnt-persist-data-in-cftransactions

Julian,

That autoManageSession made a huge difference! Thank you.

The OrmFlush() didn’t seem to help yet with my tests.

However, a few tests in, coming autoManageSession=false and adding an
EntitySave(MyCategory) within the transaction{} block has saved the data.
As soon as I added the autoManageSession=false setting, the exceptions
went away. I will test more soon and report back after I’ve had time to go
through all of my test cases, but this is really promising. Thank you!

cheers,
suttonOn Wednesday, March 18, 2015 at 3:47:09 PM UTC-4, Sutton Yamanashi wrote:

I’ve stumbled onto some strange behavior in Lucee while working through
examples in the ColdFusion ORM book by John Whish.

Specifically, many of the updates and deletes I’m attempting within a
transaction{} are failing to persist to the database (MySQL) - some of them
resulting in lengthy hibernate stack trace exception messages. This may be
related to this reported issue:
https://bitbucket.org/lucee/lucee/issue/77/orm-doesnt-persist-data-in-cftransactions

Here are a couple of videos demonstrating a couple of scenarios where this
is occurring:

http://screencast.com/t/wJNUvuNi9r

http://screencast.com/t/y3dd9sNbsHS

Orm settings in Application.cfc:

this.ormenabled = true;
this.ormsettings.dbcreate = “update”;
this.ormsettings.flushAtRequestEnd = false;

First video’s template that fails:

transaction {
// get category 1
MyCategoryA = entityLoadByPK(“Category”, 1);
MyCategoryA.setTitle(“testme”);

// do some validation
if (MyCategoryA.getTitle() == “”) {
transaction action=“rollback”;
}
}

transaction {
// get category 2
MyCategoryB = entityLoadByPK(“Category”, 2);
MyCategoryB.setTitle(“some other new title”);

// do some validation
if (MyCategoryB.getTitle() == “”) {
transaction action=“rollback”;
}
}

writeOutput(“done!”)

Second video template that fails:

transaction {
newCatTitle = “What You talking about, Willis?”;
MyCategory = EntityNew(“Category”);
MyCategory.setTitle(newCatTitle);
EntitySave(MyCategory);

}

writeOutput(“category #newCatTitle# Added!”);

There are similar problems with using entityNew() and entityDelete()
within a transaction{} block.

Thanks for all you guys do!

cheers,
-sutton

After running through a number of test cases, it seems like
the autoManageSession = false setting has fixed all but one type of my
tests.

The test that fails is when there are multiple transactions within a single
request. Before manually setting autoManageSession = false, multiple
transactions resulted in java.lang.StackOverflowError exceptions. These no
longer occur after the setting change. However, when multiple transactions
occur in a single request, If one of the transaction conditions passes
validation and commits, then all other transactions in the request commit
as well, regardless of my specifically setting them to rollback. For
example, both of the following transactions will commit (in both Railo and
Lucee) after changing autoManageSession = false:

transaction {
// get category 1
MyCategoryA = EntityLoadByPK( “Category”, 1 );
MyCategoryA.setTitle(“cat a”);

transaction action=“rollback”;
}

transaction {
// get category 2
MyCategoryB = EntityLoadByPK( “Category”, 2 );
MyCategoryB.setTitle( “cat b” );

transaction action=“commit”;
}

With that being said, I believe the work around of
setting autoManageSession = false to be too risky to be considered a “fix”
as it could create unexpected results when multiple transactions with
validation are needed in complex requests.

@Julian - thank you so much for the suggestion. It may give my team what
we need to test our applications on Lucee. However, I’d side with caution
before moving them to production on Lucee since we are going to be relying
heavily on ORM (and transactions surrounded by validation).

@ Michael - I’d suggest this issue remain open since the work-around still
creates unpredictable results in cases where multiple transaction blocks
having their own validation are needed.

cheers,
-suttonOn Wednesday, March 18, 2015 at 3:47:09 PM UTC-4, Sutton Yamanashi wrote:

I’ve stumbled onto some strange behavior in Lucee while working through
examples in the ColdFusion ORM book by John Whish.

Specifically, many of the updates and deletes I’m attempting within a
transaction{} are failing to persist to the database (MySQL) - some of them
resulting in lengthy hibernate stack trace exception messages. This may be
related to this reported issue:
https://bitbucket.org/lucee/lucee/issue/77/orm-doesnt-persist-data-in-cftransactions

Here are a couple of videos demonstrating a couple of scenarios where this
is occurring:

http://screencast.com/t/wJNUvuNi9r

http://screencast.com/t/y3dd9sNbsHS

Orm settings in Application.cfc:

this.ormenabled = true;
this.ormsettings.dbcreate = “update”;
this.ormsettings.flushAtRequestEnd = false;

First video’s template that fails:

transaction {
// get category 1
MyCategoryA = entityLoadByPK(“Category”, 1);
MyCategoryA.setTitle(“testme”);

// do some validation
if (MyCategoryA.getTitle() == “”) {
transaction action=“rollback”;
}
}

transaction {
// get category 2
MyCategoryB = entityLoadByPK(“Category”, 2);
MyCategoryB.setTitle(“some other new title”);

// do some validation
if (MyCategoryB.getTitle() == “”) {
transaction action=“rollback”;
}
}

writeOutput(“done!”)

Second video template that fails:

transaction {
newCatTitle = “What You talking about, Willis?”;
MyCategory = EntityNew(“Category”);
MyCategory.setTitle(newCatTitle);
EntitySave(MyCategory);

}

writeOutput(“category #newCatTitle# Added!”);

There are similar problems with using entityNew() and entityDelete()
within a transaction{} block.

Thanks for all you guys do!

cheers,
-sutton

I found this article where the author discusses a little bit on the
behavior of the autoManageSession setting and his preference for setting it
to false. After adding ORMFlush(); following the rollback statement (in
the first transaction) I found the rollback to be honored. This makes
sense and also aligns with something that Julian mentioned. So,
with autoManageSession=“false”, the following runs as I’d want and expect:

transaction {
// get category 1
MyCategoryA = EntityLoadByPK( “Category”, 1 );
MyCategoryA.setTitle(“cat a”);

transaction action=“rollback”;
ORMFlush();

}

transaction {
// get category 2
MyCategoryB = EntityLoadByPK( “Category”, 2 );
MyCategoryB.setTitle( “cat b” );

transaction action=“commit”;
}

cheers,
-suttonOn Wednesday, March 18, 2015 at 3:47:09 PM UTC-4, Sutton Yamanashi wrote:

I’ve stumbled onto some strange behavior in Lucee while working through
examples in the ColdFusion ORM book by John Whish.

Specifically, many of the updates and deletes I’m attempting within a
transaction{} are failing to persist to the database (MySQL) - some of them
resulting in lengthy hibernate stack trace exception messages. This may be
related to this reported issue:
https://bitbucket.org/lucee/lucee/issue/77/orm-doesnt-persist-data-in-cftransactions

Here are a couple of videos demonstrating a couple of scenarios where this
is occurring:

http://screencast.com/t/wJNUvuNi9r

http://screencast.com/t/y3dd9sNbsHS

Orm settings in Application.cfc:

this.ormenabled = true;
this.ormsettings.dbcreate = “update”;
this.ormsettings.flushAtRequestEnd = false;

First video’s template that fails:

transaction {
// get category 1
MyCategoryA = entityLoadByPK(“Category”, 1);
MyCategoryA.setTitle(“testme”);

// do some validation
if (MyCategoryA.getTitle() == “”) {
transaction action=“rollback”;
}
}

transaction {
// get category 2
MyCategoryB = entityLoadByPK(“Category”, 2);
MyCategoryB.setTitle(“some other new title”);

// do some validation
if (MyCategoryB.getTitle() == “”) {
transaction action=“rollback”;
}
}

writeOutput(“done!”)

Second video template that fails:

transaction {
newCatTitle = “What You talking about, Willis?”;
MyCategory = EntityNew(“Category”);
MyCategory.setTitle(newCatTitle);
EntitySave(MyCategory);

}

writeOutput(“category #newCatTitle# Added!”);

There are similar problems with using entityNew() and entityDelete()
within a transaction{} block.

Thanks for all you guys do!

cheers,
-sutton