ORM - Migration Guide
ORM - Migration Guide
This page covers what changed in the 5.6 ORM extension, what's coming in future versions, and how to migrate from Adobe ColdFusion.
What's New in 5.6
New ormSettings
| Setting | Description |
|---|---|
logParams |
Logs parameter bindings for SQL statements |
logCache |
Logs L2 cache activity |
logVerbose |
Logs Hibernate internals |
formatSQL |
Pretty-prints SQL in logs |
All default to false. See ORM - Logging and Debugging for full setup.
New BIFs
| Function | Description |
|---|---|
IsWithinORMTransaction() |
Returns true if a Hibernate transaction is active |
GetORMTransactionIsolation() |
Returns the current transaction isolation level |
New dbcreate Modes (requires Lucee 7.0.4+)
| Mode | Description |
|---|---|
"create" |
Creates tables if they don't exist, ignores existing |
"create-drop" |
Creates on startup, drops on shutdown |
"validate" |
Checks every mapped table exists, throws on mismatch |
Note:
"validate"currently checks table existence only — column and type validation is not yet supported (Hibernate 5.6 limitation, HHH-10882). On older Lucee versions these modes silently fall back to"none".
See ORM - Configuration for all schema management options.
Transaction Integration
- cftransaction integration — ORM operations inside a
transaction {}block participate in the database transaction. Commit flushes the session, rollback clears it - Savepoint support —
transactionSetSavepoint()works inside ORM transactions - Mixed ORM + raw SQL —
entitySave()andqueryExecute()in the same transaction now share the same connection (fixed LDEV-6234, previously caused silent failures)
See ORM - Sessions and Transactions.
Event Handling Changes
- Entity events fire before global handler — previously the global handler fired first. This lets entity-level handlers set values that the global handler can see (LDEV-4561)
- Nullability check runs after event handlers —
preInsertandpreUpdatecan now set NOT NULL properties without triggering constraint violations. Previously Hibernate's null check ran before handlers had a chance to set values
See ORM - Events.
Other Fixes and Improvements
- Property defaults apply on NULL load — when loading an entity from the database, NULL columns now get the CFC
defaultvalue applied (LDEV-4121) - Native logging bridge — Hibernate's JBoss Logging is bridged to Lucee's log system. No more log4j configuration needed
- Single connection per session — the connection provider borrows one connection from Lucee's pool per session, preventing double-borrow issues (LDEV-6156)
- Split schema export —
dbcreate="dropcreate"now runs DROP and CREATE as separate phases for better error reporting - Stricter HQL parsing — Hibernate 5.6 is stricter about HQL syntax than 5.4. Common issues:
- Implicit joins may need explicit
JOINsyntax - Some previously-accepted invalid HQL may now throw parse errors
- Entity and property names are case-sensitive in some contexts
- Implicit joins may need explicit
Coming in 7.2
Features deferred to the next major version will be listed here as they're identified.
Migrating from Adobe ColdFusion
If you're moving an ACF application to Lucee, most ORM code works unchanged. Here are the key differences:
Session Wrapper
ACF wraps the Hibernate session in coldfusion.orm.hibernate.SessionWrapper. To access the native Hibernate API, you need .getActualSession():
// ACF
nativeSession = ORMGetSession().getActualSession();
// Lucee — returns the native org.hibernate.Session directly
nativeSession = ORMGetSession();
If your code calls .getActualSession(), it will fail on Lucee. Remove the extra call.
Transaction Detection
ACF has no built-in way to check if you're inside an ORM transaction. Common hacks include:
// ACF hack — Java reflection
inTx = !isNull( createObject( "java", "coldfusion.tagext.sql.TransactionTag" ).getCurrent() );
On Lucee, use the built-in BIF: (new in 5.6)
inTx = IsWithinORMTransaction();
Hibernate Type Access
When using Hibernate's Criteria API or Restrictions directly:
// ACF — needs .INSTANCE
import org.hibernate.criterion.Restrictions;
criteria.add( Restrictions.INSTANCE.eq( "name", "test" ) );
// Lucee — static fields are accessible directly
criteria.add( Restrictions::eq( "name", "test" ) );
Logging
ACF uses log4j configuration for Hibernate logging. Lucee 5.6 has a native logging bridge — configure everything through ormSettings and Lucee's log system. See ORM - Logging and Debugging.
Error Messages
Lucee wraps some Hibernate exceptions differently than ACF. The underlying error is the same, but the exception type and message format may differ. Check cfcatch.cause or cfcatch.rootCause to get the original Hibernate exception.
autoManageSession
Both ACF and Lucee support autoManageSession, but the implementation details differ slightly. If you rely on specific session lifecycle timing, test thoroughly after migration.
Migrating from Older Extension Versions
If you're upgrading from the 5.4 extension:
- Check HQL queries — Hibernate 5.6 has stricter parsing. Test all HQL queries
- Check event handler order — entity events now fire before global handlers
- Check NULL property defaults — loading a NULL column now applies the CFC
defaultvalue - Check transaction behaviour — ORM now participates in
cftransactionblocks properly - Update logging configuration — the new logging settings replace any manual log4j setup
What's Next?
- ORM - Configuration — all ormSettings including 5.6 additions
- ORM - Sessions and Transactions — transaction integration details
- ORM - Events — event firing order changes
- ORM - Troubleshooting — common errors and fixes