Notes: Advanced ORM in ColdFusion 9

These are notes from Adobe MAX 2009 about advanced ORM in ColdFusion 9.

Join Mapping. You can have a CFC whose primary table is “Person”, but it has properties that fetch values from a joined table, such as the “City” property from an “Address” table. Interesting.

ORM Initialization. When application first starts, it looks to see if ORM is enabled. If so, it creates/loads the Hibernate configuration, the loads Hibernate mapping files, searches for persistent CFCs (you can point it at only a particular directory to speed things up), generate Hibernate mapping for persistent CFCs, then even generate the schema on the database if it doesn’t exist, and then finally build the Hibernate Session Factory. Once this is done, it will not occur again unless you tell it to, because this initial setup is an expensive operation. You can use ormReload() to force it.

ORM Session. All ORM operations happen in the session. It provides some simple caching. The session tracks changes made to the objects. So it doesn’t actually execute SQL until a session is flushed, which happens when the request completes or when you force it with ormFlush().

When using CFTRANSACTION, the Hibernate session will be flushed and closed at the end of your CFTRANSACTION.

Object States. When you create an object with EntityNew(), CreateObject(), etc, the object is transient and is not known by Hibernate yet. Once an object is saved or loaded, it is in a persistent state. The kicker is “detached” objects. If the Hibernate session ends, and object that you have will become “detached” since the session ended. So if you have lazy loading for your object, for instance, it will throw an error because Hibernate has nowhere to lazy load the object’s data. However, you can use EntityMerge() or redo an EntityLoad() to bring it back into a persistent state.

Concurrency Control. You can use the “optimisticlock” attribute of a CFC to “All”, “Dirty”, “Version”, or “None” to control how record updates occur. “Version” is the default which uses a timestamp to check the version of the record vs. the object. “All” does a where statement of all record fields, and “Dirty” only handles the changed fields.

Fetching strategy. How will you fetch relationships of tables? “Immediate”, “Lazy”, “Eager”, or “Batch” fetching. “Immediate” fetches everything immediately. The default “Lazy” fetches things on demand. “Eager” fetching fetches everything in a single SQL statement, good for frequently used one-to-one relationships. There was a bit of confusion in regard to “Batch” fetching.

Caching. Session-level cache fetches data the first time and will not reload subsequent requests. EntityReload() will force a reload. Secondary-level cache can cache data across Hibernate sessions. It can be in-memory, disk, clustered. They have the default caching engine as EHCache.

How to use secondary cache? Enable it first. In application.cfc, use ormsettings.secondarycacheenabled=”true”. Then in your ORM CFC, the cacheuse=”” attribute defines the caching strategy (such as “read-only”, the most performant), and cachename=”” defines the name of this specific cache.

Secondary cache can also be used on relationships. And when using ormExecuteQuery() functions to use HQL to query the database, you can cache as well with cacheable=”true” as one of the options. This can be used in EntityLoad() too.

When cleaning up caches, there are ormEvictXXX() functions to remove entities, collections, and queries.

Event Handling. Hibernate lets you set ormsettings.eventhandling=”true” to have many CFC level events, like preLoad(), postLoad(), preInsert(), postInsert(), preLoad(), postLoad(), etc. This can be used for logging or other nifty features. Wow! That’s awesome. Nice hooks.

Interesting user questions. One gentleman asked about using an XML file as a datasource through Hibernate. That would be interesting to try/use.

This session could have been 90 minutes. There are a lot of advanced things that can be done with the ColdFusion integration with Hibernate from the ColdFusion API.

4 Responses to “Notes: Advanced ORM in ColdFusion 9”

  1. Brad Wood Says:

    Thanks for posting the updates. I wish I could be at Max this year, but alas I must depend on people such as yourself to keep me filled in on the Adobe goodness being spread around down there. :)

  2. James Brown Says:

    We’ll be posting this session on AdobeTV shortly if you want to watch the presentation online. http://tv.adobe.com

  3. Kerr Says:

    Ahh, thanks for the note on ormsettings.secondarycacheenabled=”true”! I was at the office yesterday trying to figure out why my cache setting on a relationship wasn’t working, and about pulled my hair out. Lots of stuff to learn here with ORM, dare I say as much as when CFCs were introduced.

  4. haroon Says:

    Hi Dear

    I need your help in ColdFusion ORM Optimistic Concurrency Control. I am using Optimistic Concurrency Control in our going on project (CF orm based).
    I checked version and timestamp both type. Version and timestamp incremented correctly when record is updated but same time if other user updated that record, hibernate not throwing Exception..

    Code is here(in attachment also):

    Database Table:
    CREATE TABLE `campaign_type_m` (
    `Id` int(11) NOT NULL AUTO_INCREMENT,
    `Name` varchar(255) DEFAULT ”,
    `CreatedDate` datetime DEFAULT NULL,
    `CreatedId` int(11) DEFAULT ’0′,
    `ModifiedDate` datetime DEFAULT NULL,
    `ModifiedId` int(11) DEFAULT ’0′,
    `IsActive` tinyint(1) DEFAULT ’0′,
    `IsDeleted` bit(1) DEFAULT NULL,
    `version` int(11) DEFAULT ’0′,
    PRIMARY KEY (`Id`),
    KEY `FK95B65EB7B0BC1027` (`CreatedId`),
    KEY `FK95B65EB7D46C1FC8` (`ModifiedId`),
    KEY `FK95B65EB793B1B88E` (`CreatedId`),
    KEY `FK95B65EB7B761C82F` (`ModifiedId`)
    ) ENGINE=MyISAM AUTO_INCREMENT=24 DEFAULT CHARSET=utf8

    Value object: campaign_type_m.cfc

    Service: campaign_type_mService.cfc

    application: Application.cfc

    This is my code. Please check. Everytime version is increasing But when same record updated by different user. System showing “Record Updated”. While after updated one user when another user try to update, hibernate should throw an exception because record already update by someone without your knowledge. I am doing something wrong.

    Please check.

    Many many thanks

  Theme Brought to you by Directory Journal and Elegant Directory.