DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
Securing Your Software Supply Chain with JFrog and Azure
Register Today

Trending

  • Using Render Log Streams to Log to Papertrail
  • How To Use Pandas and Matplotlib To Perform EDA In Python
  • Never Use Credentials in a CI/CD Pipeline Again
  • Automating the Migration From JS to TS for the ZK Framework

Trending

  • Using Render Log Streams to Log to Papertrail
  • How To Use Pandas and Matplotlib To Perform EDA In Python
  • Never Use Credentials in a CI/CD Pipeline Again
  • Automating the Migration From JS to TS for the ZK Framework
  1. DZone
  2. Data Engineering
  3. Databases
  4. Some recent ColdFusion ORM Pain

Some recent ColdFusion ORM Pain

Raymond Camden user avatar by
Raymond Camden
·
Apr. 11, 13 · Interview
Like (0)
Save
Tweet
Share
3.61K Views

Join the DZone community and get the full member experience.

Join For Free

I'm working on a relatively simple ColdFusion ORM application. It is focused around a core entity type called Content. This entity type is rather large, around 50 or so properties. As you can imagine, some of the properties are simple, some are many-to-one, and some are many-to-many. I ran into some very frustrating issues though and I thought I'd share them.

Invoke

The first issue I ran into was a bit of code I used to set a set of simple values. I've got a bunch of values that don't (really) need any validation and can simply be copied from a structure directly into the entity. So I created a simple list and iterated over it to set my values.

var simpleList = "subsegment,topic,topicupdatedby,task,need";

for(var x=1; x lte listLen(simplelist); x++) {
	var li = listGetAt(simpleList, x);
	invoke(content, "set#li#", data[li]);
}

Simple, right? But note the use of invoke. This is a ColdFusion 10 addition that lets you call dynamic methods in CFCs. I noticed that none of my data was actually persisting. Why?

Turns out - in order for my calls to setX (where X is a entity method) to work, I have to pass the value as a structure. Here is the modification:

for(var x=1; x lte listLen(simplelist); x++) {
	var li = listGetAt(simpleList, x);
	invoke(content, "set#li#", {"#li#"=data[li]});
}

Why? I've got no freaking clue. To be fair, the docs show passing a structure of arguments, but they don't explicitly state that you must do this. Even worse, an error was never thrown when I passed the argument as a simple value instead. I hate errors that are ignored.

Error Reporting

The second issue was much, much worse. Not that it was difficult to fix once I knew what the issue was, but the problem was in how the issue was reported.

As I mentioned above, my entity has simple properties, many-to-one properties, and a many-to-many. I began by coding in the simple properties (using the technique I described above). I then did my many-to-one. I then did the many-to-many.

I noticed that my join table was not populating. I didn't get an error though. What makes this more frustrating was that I could dump my entity before the save operation and clearly see my related data in the entity. Yet I'd run the save, it would insert a new record into the core table, and just... do nothing else. Again - no damn error. Anywhere.

So I backed up a bit. First I decided - let's turn off the auto flush feature and use transactions. I didn't think that would help per se, I just decided to give it a try. All of a sudden I got something - an error:

coldfusion.orm.PersistentTemplateProxy cannot be cast to java.util.Collection

Ok... so.... first off. Why would ColdFusion persist the entity, have a problem, and just not report it until I started handling the flush myself with a transaction? I can't imagine any reason why that would make sense.

Here's where things got even more interesting. I commented out the code handling the many-to-many and I still got the error!

On a whim, I decided to comment out the code handling 3 of my many-to-one properties. All of a sudden, that fixed the issue. I then uncommented out the many-to-many and it still worked fine (and persisted data to the join table). So obviously my issue was in the many-to-one blocks.

When you work with relationships, you're supposed to ensure you set both sides of a relationship. You can sometimes get by without, but you really shouldn't. In order to make this simpler, you can simply use some custom code in the core entity and have it do both sides of the relationship. So for example, here is one of those methods:

public any function setSegment(id) {
	var segment = entityLoadByPk("segment", id);
	variables.segment = segment;
	writelog("added a segment");
	segment.setContent(this);
}

Simple, right? In my content entity I call setSegment. The method handles the logic of translating an ID to an entity, setting it, and doing the reverse side. But something in here was wrong.

At no time, though, was I told what was wrong. Outside of the error message I pasted above, I was lost.

Finally I started commenting the lines in that method and got it down to this:

segment.setContent(this);

And then it hit me. On the content side, it has one segment. On the segment side, it has many content entities.

So right away I've learned that the built-in methods are apparently not validating for the cases when an array is required.

Ugh.

Database Relational database

Published at DZone with permission of Raymond Camden, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Trending

  • Using Render Log Streams to Log to Papertrail
  • How To Use Pandas and Matplotlib To Perform EDA In Python
  • Never Use Credentials in a CI/CD Pipeline Again
  • Automating the Migration From JS to TS for the ZK Framework

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com

Let's be friends: