ColdFusion ORM is far to complicated than it has to be Part II.

It seems that nobody has fully understood what I was trying to say in the previous post, and I thought I would explain it in a more step by step process.

Before I begin describing this, Adobe has done a good job of getting this into ColdFusion. However there are areas that are just to damn confusing, and could be made simpler, as well as making sure the Documentation in both the online and ColdFusion builder are not full of errors and code that do not work.

Relationship mapping of components is just one of these areas. And how is that so.

Lets have a quick look at how it should look like, and how easy it should be.

Artist.cfc
/**
* @persistent
*/
Component {
   property name="artistid" generator="increment" fieldtype="id";
   property firstname;
   property lastname;
   property address;
   property city;
   property state;
   property postalcode;
   property email;
   property phone;      
   property fax;
   property thepassword;
   property name="art" fieldtype="one-to-many" cfc="Art";
}

Art.cfc
/**
* @persistent
*/
Component {
   property name="artid" generator="increment" fieldtype="id";
   property artname;
   property price;
   property largeimage;
   property mediaid;
   property issold;
}

According to Rupesh from Adobe the above code should work. instead, we get an error like this.

Error while resolving the relationship art in artist. Check the column mapping for this property.

This basically says that what I was trying to say in my previous post, makes the ORM more complicated than it should be, but it doesn't end there.

So if we follow the documentation and what Adobe is saying, we need to define the relationship on both entities.

So lets modify the Art.cfc by adding the following:

property name="artist" fieldtype="many-to-one" cfc="Artist" ;

However we get this error message now.

Error while resolving the relationship artist in cfc art. Check the column mapping for this property.

So why is this happening, well even though it is optional you still need to apply the fkcolumns to the above code. So we now have to add the following to both of our components.

Artist.cfc
property name="arts" fieldtype="one-to-many" fkcolumn="artistid" cfc="Art";

Art.cfc
property name="artist" fieldtype="many-to-one" fkcolumn="artistid" cfc="Artist" ;

So as you can see what could have been simple to begin with, has ended up being more complicated than it should have been.

With another programming language, we only need to define what we had in our very first example and everything else was worked out for us.

The thing with relationships like many-to-one is that we should never need to defined the relationship in our persistent component, by doing so is just over complicating something that should be more simpler than it is.

So even though we also have something that is optional as in the fkcolumn, it become a required field in this example as well, making it even more complicated than it should be.

I hope that Adobe take this information, look at how it is making our jobs harder and not easier. And hopefully address the problem as quickly as possible, and make our jobs as developers easier in the long run, and not frustrating to those who are still not up with table relationships.

The idea of having an ORM in a programming language like ColdFusion is to have to not worry about learning to much. With the approach I have looked at, it tells us that we do not need to know about the actual relationship of the tables. We just tell ColdFusion that we want to know that we have a one to many relationship on one of our components, the developer should not need to know how to make it work by defining a relationship on both components, nor should they have to worry about the foreign keys.

By removing these things, the developer can go on and continue with writing an Application. But for those who want that finer, granular control they can still use the foreign key.

I hope that clears it up more.



  • Henry Ho's Gravatar No, you DON'T have to define the relatinship on both entity.

    This should work for unidirectional one-to-many relationship:

    property name="art" type="array" fieldtype="one-to-many" cfc="Art" fkcolumn="XXX";
    # Posted By Henry Ho | 11/5/09 2:31 PM
  • Andrew Scott's Gravatar Henry, it doesn't that is why I did it step by step. And why you can see the error messages from each step as well.
    # Posted By Andrew Scott | 11/5/09 9:47 PM
  • Rupesh Kumar's Gravatar Andrew, it might come as a shocker but ColdFusion cannot read your mind and we never claimed that :-).

    If the table exists and there is no constraint defined on the tables for establishing the relation, there is no way ColdFusion can figure that out. It DOES figure out the 'fkcolumn' if

    - the tables do not exist and you want ColdFusion to create the tables for you OR

    - the constraints are defined on the table.

    In your case, there is no constraint defined on the table and you have omitted fkcolumn information, hence the error that you see. I would be curious to know what Grails does for the same table in the same datasource.
    # Posted By Rupesh Kumar | 11/5/09 10:04 PM
  • Sumit Verma's Gravatar You don't need to specify the relationship in both enrity. Your issue was that you didn't specify fkcolumn attribute.
    # Posted By Sumit Verma | 11/6/09 11:17 AM
  • Andrew Scott's Gravatar @Sumit - I know what I did not do, the article should be read in the entire context. I am saying that ColdFusion can make it simpler, I suggest you read the post agina please.

    I am not surprised that so many people have not actually read what I am asking for here, instead of seen this as me having a problem with my code.
    # Posted By Andrew Scott | 11/6/09 11:50 AM
  • Andrew Scott's Gravatar @Rupesh - The one thing that has annoyed me the most is your blind sided attitude. First I am going to say this for the last time to you, and this time it is public.

    Adobe could have learned a lot from grails when it comes to how they implemented their GORM, the approaches that they have put in place has introduced better Rapid Application Development than ColdFusion in so many areas.

    This topic is an example and testimont to that, and I hate to say it. But it sounds like to me that the Software Engineers at Adobe have had no interest or desire to even check out how the competition not only implemented this stuff. But how much more RAD it actually is.

    So far and this will sound harsh, and I really don't care. But Adobes attitude on this matter is we will do it our way, which is fair enough, but when you also claim that you have a RAD product that in areas is not, makes me think that you are not interested in improving the product to a point where we suggest ways to make it better.

    Instead you sit back and think, well we know our stuff and I am sure you do. But were are the people who are going to be wanting to use this feature on a daily basis, and here is an example of how you could do it faster and with less code.

    And your only response to me is how does your beloved grails do it, I brought this up so many times to you personally over the last 12 months, and you have never acknowledged that you have checked out how the competition does it, and your response clearly indicates that Adobe once again is not interested in suggestions that can improve the product, or at best help us to do things quicker and very RAD.

    As a Software Engineer yourself Rupesh, you know as well as I do and I think if you bothered to read what I said that the foreign keys could be generated by ColdFusion, however if the developer wants finer control they have the ability to define the foreign keys using the fkcolumn attribute. I hinted at this and it appears to have gone unnoticed by everyone.

    So far you have continually proved that you don't read between the lines, and you have continued to not see the trees from the forest.

    So the question now is Rupesh, can ColdFusion do something like this

    class Author {
    static hasMany = [ books : Book ]
    String name

    }

    class Book {
    Author author
    String title
    }

    Do you notice how this tells the domain class Author that we have a onetomany relationship, and their is nothing more nothing less than what the developer needs to know to get going.

    If your attitude is that you can only try to guess, and not use defaults or ways to fill in the gaps then your logic is flawed. For example in an non InnoDB grails can even still work here, because there is no such thing as fk's in MyISAM schemas.

    So Rupesh, are you brave enough to begin to think outside the square or are you saying that we as people who use ColdFusion has to tell you exactly how this can be done!!

    The problem here and this is where you are not listening, is a typical example that was brought up a number of times to help make our life easier, and Adobe just ignored us. There are many ways to auto do things under the hood, in this case if something doesn't exist there is also an oppurtunity to look at ways to do it magically. And Foreign Keys, could be generated by ColdFusion and yet it seems that it is the attitude by your Rupesh that this is can't be done.

    If this sounds like an attack on you personally Rupesh, please don't take it that way. It is a public frustration that I am personally sick of Engineers who sit back, and ignore people who are going to be using the product when we give suggestions on how it could have been improved.

    And I hope that this will be something that Adobe can take into consideration for either a next minor release, or even next major release.
    # Posted By Andrew Scott | 11/6/09 12:06 PM
  • jason's Gravatar It appears that they have not done anything regarding this issue over 1 year later lol. I have been here scratching my head trying to figure out what was wrong with my code and why I got the same error you were receiving. Once I tried your example code it resolved my error as well. Thank you for the help!
    # Posted By jason | 2/3/12 2:13 PM