CF9 ORM relationships – hasProperty oddity

In my CF9 ORM application, I have a magazine object. Each magazine has a single genre (e.g. Craft, Sports, etc.) – so I have a many-to-one relationship set up on the magazine.cfc:

component output="false" persistent="true"
{
	// identifier
	property name="magazineid" fieldtype="id" setter="false" generator="identity";
	
	// properties
	property name="title";
	property name="genre" cfc="genre" fieldtype="many-to-one" fkcolumn="frn_genreid";
}

The genre.cfc looks like this:

component output="false" persistent="true"
{
	// identifier
	property name="genreid" fieldtype="id" setter="false" generator="identity";
	
	// properties
	property name="genre";
	property name="magazines" cfc="magazine" fieldtype="one-to-many" fkcolumn="frn_genreid";
}

It all works nicely, until I want to try removing the genre from the magazine.

If I create a new magazine entity, the genre property contains an empty string (confirmed by dumping the object). And the hasGenre() method returns false.

If I load an existing magazine entity, the genre property contains a genre object, and hasGenre() returns true.

So to try to remove the genre, I use:

magazine.setGenre( '' );

to set the genre property to an empty string, just like in the new entity – but hasGenre() still returns true – why?

If I instead use:

magazine.setGenre( {} );

to set the genre property to an empty struct, hasGenre() now returns false, and everything works OK.

But what is the difference between the empty string that I set manually, and the empty string that’s present when a new entity is created? And why do they return different results for hasGenre()?

 

Comments

Sam Farmer

Did you try using the removeGenre() method?

18 August 2010, 14:01
Reply
Seb Duggan

Because the magazine entity has only one genre, it doesn't have the addGenre() and removeGenre() methods - they are only there for one-to-many and many-to-many relationships...

18 August 2010, 14:30
Reply
Brian Kotek

First, you really should be setting one side as the owning side in bidirectional relationships. More at http://www.barneyb.com/barneyblog/2010/04/09/dont-forget-inverse-true/ and http://www.briankotek.com/blog/index.cfm/2009/12/21/More-on-CF9-ORM-Relationships

Second, the CFDUMP is lying to you. Well, not really lying, but what you see as an empty string is actually a null value. And that's why the two are different. When you set the genre to an empty string, the hasGenre returns true because the genre is not null.

First, I'd highly recommend using a relationship management method to enforce the integrity of your bidirectional relationship. You can find out more at the above links, as well as: http://www.barneyb.com/barneyblog/2010/04/14/domain-model-integrity/

Second, if you actually want to set the value to null, you need to use JavaCast:

setGenre( JavaCast( 'null', 0 ) );

Hope that helps.

18 August 2010, 16:30
Reply
Seb Duggan

Thanks Brian - some very useful stuff in there!

I'm only just starting with ORM, so I've still got a lot to learn; but I'm putting together a collection of some very useful blog posts...

18 August 2010, 20:03
Reply
Post a Comment
  1. Leave this field empty

Required Field