Using structures/maps instead of arrays in ORM
By default an ORM relationship is an array. Using a structure (map for non-ColdFusion programmers) is very easy and provides nice options. Lets start with a simple relationship between of users and addresses.
User.cfc
1component persistent="true" {
2property name="userId" fieldtype="id" generated="always" generator="native";
3property name="name" ormtype="string";
4
5property name="address" fieldtype="one-to-many" cfc="address" fkcolumn="userId" inverse="true";
6}
2property name="userId" fieldtype="id" generated="always" generator="native";
3property name="name" ormtype="string";
4
5property name="address" fieldtype="one-to-many" cfc="address" fkcolumn="userId" inverse="true";
6}
Address.cfc
1component persistent="true" {
2property name="addressId" fieldtype="id" generated="always" generator="native";
3property name="type" ormtype="string";
4property name="street" ormtype="string";
5property name="city" ormtype="string";
6property name="state" ormtype="string";
7
8property name="user" fieldtype="many-to-one" cfc="user";
9}
2property name="addressId" fieldtype="id" generated="always" generator="native";
3property name="type" ormtype="string";
4property name="street" ormtype="string";
5property name="city" ormtype="string";
6property name="state" ormtype="string";
7
8property name="user" fieldtype="many-to-one" cfc="user";
9}
A single user object with two addresses would look like this:
Now, if we want to find out if the user has a work address we need to loop through getAddress(). Thats ok but by converting the relationship to a struct its possible to then use structure functions. Here is the relationship in User.cfc defined to return a structure:
1property name="address" fieldtype="one-to-many" cfc="address" fkcolumn="userId" inverse="true"
2 type="struct" structkeycolumn="type";
2 type="struct" structkeycolumn="type";
A dump of the user object now looks like:

Which means we can use code like this, in particular line 3:
1<cfset u = entityLoad("user")>
2<cfloop array="#u#" index="user">
3 <cfif structKeyExists( user.getAddress(), "work" )>
4 <cfdump var="#user.getAddress()["work"]#">
5 </cfif>
6</cfloop>
2<cfloop array="#u#" index="user">
3 <cfif structKeyExists( user.getAddress(), "work" )>
4 <cfdump var="#user.getAddress()["work"]#">
5 </cfif>
6</cfloop>
For reference here is the Application.cfc to set up Hibernate/ORM:
1component
2{
3this.name="structsDemo";
4this.ormEnabled=true;
5this.datasource="cfartgallery";
6this.ormsettings = { dbcreate="update" };
7
8}
2{
3this.name="structsDemo";
4this.ormEnabled=true;
5this.datasource="cfartgallery";
6this.ormsettings = { dbcreate="update" };
7
8}

That's an excellent post thanks. I often forget that you can use structs for relationships, probably because I never really put much thought into the possible use cases for it.
This makes really great sense, and is an excellent approach.
Thanks,
Robert
Reading this does reawaken my desire for more intelligent collections in ORM entities other than just static arrays and structs. Something which makes searching and filtering the collection much simpler.
cfwheels has a great implementation, similar to that of Rails, where in your use case I wouldn't have to care about what collection we use (array vs. struct), nor would I have to run the structKeyExists(), I could search/filter the collection like so:
User.Address.findWhere(type='work');
I would love to see enhancements in the cf-orm implementation to do something like this.
Robert
The wheels/rails example is cool. In your example does that return just users who have a work address? And for those does it return there other addresses as well?
I think you can do something like this with HQL / ORMExecuteQuery()