Photo from Chile

CF9 ORM Gotcha - Adding Items to a Struct Collection

I was just bitten by this one, so I thought I'd quickly blog it to help anyone else who comes across it. If you've got a one-to-many or a many-to-many property in your ColdFusion ORM entity, and you've specified that the collection of objects should be stored as a struct, when adding an item to that struct you must pass both the key for the item and the item itself into the add method. For example, using the following Department object:

view plain print about
1component persistent="true" output="false" entityname="Department" {
2    property name="DeptId" fieldtype="id" generator="native";
3    property name="Name";
4    property name="Users" fieldtype="one-to-many" type="struct"
5        cfc="User" fkcolumn="DeptId" singularname="User"
6        structkeycolumn="UserName" structkeytype="string" cascade="save-update";
7}

Forgetting that I had to specify the key for the struct as well as the object, my first take at adding a User object to the Department's collection of Users was something like this:

view plain print about
1Department = entityLoad("Department",1);
2User = new User();
3User.setUserName("Bob");
4Department.addUser(User);
5entitySave(Department);

Unfortunately, this code throws an error stating "The User parameter to the ADDUSER function is required but was not passed in." Being a bit dim-witted, I was totally confused by this. "Hey," I said to my computer, "I know that I'm passing a User object into the method." It took me awhile to remember that I had to pass both key to the struct and the User object into the addUser() method. Changing the code to:

view plain print about
1Department = entityLoad("Department",1);
2User = new User();
3User.setUserName("Bob");
4Department.addUser("Bob",User);
5entitySave(Department);

Did the trick. So remember:

  • When adding an item to a collection that is a struct, you must pass both the key to the struct and the object into the add method.
  • You must pass the key to the struct in as the first argument, and the object as the second argument.

Conversely, when removing an item from a struct collection using the remove method, you only need specify the key to the struct. I hope this tidbit saves someone else the time that ColdFusion stole from me. ;-)

TweetBacks
Comments
Bob, as I have not done much ORM yet, forgive me if this is a silly question; but, does the ORM system do any validation on the Key that you pass in? Does it affect the way the data is persisted to the database (or will the persistence use the value as defined by the CFProperty structKeyColumn value?

Could you do something like:

Department.addUser( User.getUserName(), User )?
# Posted By Ben Nadel | 1/23/10 9:05 PM
That is a very good question. Ben. So good, in fact, that it spawned its own blog post here: http://www.silverwareconsulting.com/index.cfm/2010..., in which I explore the question of validation of the key.

In answer to your final question, yes, that code would be perfectly acceptable, and probably a good idea.
# Posted By Bob Silverberg | 1/25/10 7:34 AM