Monday, March 17, 2014

Working with ColdFusion Offline AIR Features

I've recently started working on a new application. Based on the requirements, and having the freedom to choose the technologies involved, I decided it would be a good time to revisit the Offline AIR features that were introduced in CF9 (but for which I’m utilizing in CF10).

Although I've never finished an actual application using this feature, I did play around with it quite a bit when it was introduced. I was very impressed with it and always thought it was a bit underrated at the time. Although times have changed, if you’re still a ColdFusion and/or Flex developer (who still does either of those anymore, right?) you may still find this feature set to be pretty slick.

After not having looked at it in a few years, I needed to go through the documentation to refresh myself on how it all works and was, unfortunately, reminded on how poor the documentation was. So I’m posting this as a reminder to myself on how to accomplish a few things.

Issue #1: Specifying target entities when defining client side relationships.

This is absolutely nowhere to be found in the documentation. Even the full application example code doesn't show how this done. The example code assumes that all your entities are in the root of the application (which is never the case), and therefore, show the syntax of specifying a target entity like this:

[OneToMany(targetEntity="Department", mappedBy="department")]
public var depts:ArrayCollection;

If the 'Department' entity was in the root of the application, that'd work perfectly. But since it's probably not, you’d assume you just specify the fully qualified class name with package structure as the value. That’s close, but doesn't quite work. The actual syntax would be something like this:

[OneToMany(targetEntity="com.domain.application.model::Department", mappedBy="department")]
public var depts:ArrayCollection;

Notice the double colons separating the package path and the class name. Again, that syntax is nowhere to be found in the official documentation.

Issue #2: What to specify for the mappedBy attribute in the relationship metadata.

The code example above demonstrates the OneToMany relationship as defined in an Employee entity, between an employee and departments (assuming an Employee can belong to many Departments – which is usually the other way around – and just makes the example even more confusing - but I digress). 

Yet, it never really explains what the value "department" is referring to in the mappedBy attribute. And if you were to try and figure it out by studying the example code, it would only confuse you more because the code is wrong. 

The mappedBy attribute is intended to refer to the property in the targetEntity (Department) that maps the inverse (ManyToOne) side of the relationship. That's my definition… not a definition you'll find anywhere in the documentation. Based on the code above, it would expect a property in the "Department" entity, named "department" which refers to an employee. That's obviously a documentation bug and should probably be written as:

[OneToMany(targetEntity="Department", mappedBy="employee")]
public var depts:ArrayCollection;

More issues to come?

I'm sure I'll run into more documentation issues as I get further in development and will update this post as they occur.