CFConversations podcast #5: interview with Liz Frederick and Nafisa Sabu of TeraTech/CFUnited

Hey, folks, the first CFConversations interview podcast is now available. Check it out--you can either subscribe to the podcast via iTunes (just search for "CFConversations") or download each episode directly from the CFConversations website.

Episode 4 of CFConversations podcast:: ideas for promoting CFML

The fourth episode of the CFConversations podcast, the last of the three episodes recorded at CFUnited, was released early this morning.

This episode focuses on some ideas that came out of Brian Meloche's conference session on promoting the use of CFML outside of the ColdFusion community. Check it out!

Some random post CFUnited thoughts

Now that CFUnited's over (at least for me) and I've had some time to rest and mull over things, I wanted to post a few random thoughts and opinions:

  • The entire L'Enfant Plaza Metro station (columns, walls, even some of the Metro railcars that passed through) was one big ad for Adobe LifeCycle. The message: LifeCycle can help the government manage and distribute PDF forms. Unusual? I don't get down into DC too often, but I'd never seen any one company take over an entire station like that before. I want to see more of this high-visibility marketing from Adobe, especially for ColdFusion.

  • Sean Corfield's new asynchronous event-driven framework, Edmund, looks very cool. Being able to fire off events and have them bubble up through the framework much like what you can do in Flex is a very appealing idea.

  • Twitter once again proved to be a useful tool. I found it a lot easy to "tweet" what was going on instead of writing it up on the blog, and thanks to Nafisa Sabu and Elliot Sprehn of TeraTech, anyone who visited the CFUnited website could read the tweets of the conference-goers who had "friended" the CFUnited Twitter account. Hopefully a few folks found my tweets to be useful.

  • While the proposed integration of Hibernate in ColdFusion 9 sounds neat, I think Transfer is still going to be the ORM of choice for many developers, both now and in the future, for some of the reasons Mark listed in his blog and because Transfer works/will work on a larger number of CFML platforms (CF7, CF8, and probably OpenBD and Railo).

  • The discussion about whether or not ColdFusion and ColdFusion development is becoming too Java-like isn't over yet. I met a developer who made the point that it seemed strange (and stupid) to him that we're trying to entice Java developers to use CFML because it makes development faster and easier while we seem to be gravitating towards adding complexity to our development process and our code.

    I made the usual argument that regardless of the focus on OOP in the ColdFusion blogging community, no one was advocating removing those aspects of ColdFusion that make CFML easy to learn and use, and that even OO-style programmers will admit that there are some situations where using an OO application framework is overkill, but he wasn't entirely convinced.

    It made me wonder: if Adobe does develop a teaching curriculum as part of their effort to get ColdFusion adopted in schools, will that curriculum take advantage of CFML's traditional low learning curve, or will they emphasize an OO-style of programming from the get-go?

  • Some promising ideas came out of Brian Meloche's session on promoting ColdFusion/CFML outside of the community. The existence/promise of OpenBD and Railo and Adobe's decision to make ColdFusion free for educational use has opened up a whole new world of possibilities. You should be hearing about these ideas soon, either via the CFConversations podcast or some other channel.

  • Which reminds me, you should check out the CFConversations podcast if you haven't done so already. And I would say that even if I wasn't involved with the project. :)

Going to CFUnited tomorrow

Well, CFUnited begins tomorrow, so I'll be getting up a bit earlier than usual so I can drive to the nearest Metro station and head down into D.C.

The last time I attended CFUnited was back in 2005, so it'll be interesting to see if the conference has changed any in terms of atmosphere and organization since then. Certainly the venue will be different; hopefully that means the wireless network will be more robust/reliable.

And this time I won't be ducking out of lunch to settle on a new house (but hey, I did make it back in time for the next round of sessions).

I probably won't post any new blog entries during the conference (it takes me too darn long to come up with what I really want to say), but I might post a snippet or two about what's going on via Twitter. If you're interested in listening in on those "tweets", you can just follow me on Twitter for the next few days: my Twitter handle is bcswartz.

As for any of my fellow conference-goers (if you're listening), if you don't already use Twitter, you might want to make use of it during the conference. I don't know if Twitter is going to serve as a communications channel for what's going on and where people are meeting up like it did at cf.Objective(), but I imagine if nothing else the CFUnited folks will be making use of the CFUnited Twitter account to send out notices and what not. You can either use Twitter via the Twitter website and refresh the page occasionally, or you can use a Twitter desktop app like Twhirl (built with Adobe AIR).

Of course, that's all moot if we manage to overload the wireless network at the conference. :)

Anyway, looking forward to seeing everyone there!

What the CFUnited folks want to know

The folks running CFUnited have invited ColdFusion bloggers to answer some questions about the conference on our own blogs.

Sounds like a good excuse for an easy blog post, so here goes...

"What are you looking forward to most?"

While there are a few sessions I'm particularly looking forward to, what I'm looking forward to most is conversing with my fellow developers and sharing ideas.

"Which speaker will most likely end up on your camera?"

Hopefully none of the speakers will fall on my camera. Maybe I should just leave the camera at home; safer for everyone involved.

"What do you plan to do outside conference time?"

Hang out with fellow conference-goers, maybe help some of the out-of-town folks find the places they want to visit (I'm no expert on D.C., but I know where most of the notable stuff is and can find my way around).

Since I'll be commuting between home and the conference each day, I probably won't be hanging around too late 'cept for Friday night.

"Fill in the blank: I will mainly be around the ______ booth."

The popular booth, to find out why it's so popular. I'm curious like that.

"Do you have a new project you are working on and will reveal it at CFUnited?

Nothing I'm working on in my personal time really constitutes as a "project," per se, so no.

But if someone does want to announce and show off their project at CFUnited, I'd suggest going to the CFUnited wiki and scheduling a block of time in the Special Attendee conference room (the Lafayette room) so you have somewhere to show off your project. The schedule for that room is far from booked.

Using a Transfer decorator to get related records within the same table

One of the benefits of using the Transfer ORM in your application is that if you define the relationships between your tables in the Transfer XML configuration file, you can retrieve any objects related to your current object through a variety of functions.

However, sometimes you need to relate records within the same table. For example, in my current project, I have a table of item records which need to be arranged in a hierarchy of unknown depth: one set of items could have two levels of hierarchy, another three levels. Each item, therefore, can have one parent item above it (identified by a parentId field in the record) in the hierarchy and any number of children below it (and all the child records have the current item's ID as their parentId value).

How can you use Transfer to access these in-table relationships? One way is by using a decorator object. As the Transfer documentation explains, a decorator is a CFC file you write yourself that extends the TransferDecorator CFC that comes with Transfer. You associate your decorator with the Transfer object that represents the table in your Transfer configuration file so that when a Transfer object for a record in that table is generated, the functions you define in your decorator become part of that object.

So say I define a Transfer object called "Item" in the package "example". Here is the XML in the Transfer configuration file:

<package name="example">
<object name="Item" table="itemsTable" sequence="itemId_seq" decorator="com.itemDecorator">
<id name="itemId" type="numeric" />
<property name="setId" type="numeric" column="setId" />
<property name="itemTitle" type="string" column="itemTitle" />
<property name="itemText" type="string" column="itemText" />
<property name="itemOrder" type="numeric" column="itemOrder" />
<property name="parentId" type="numeric" column="parentId" />
</object>
<!-- Etc. -->
</package>

The decorator to be called is the itemDecorator.cfc in the "com" directory. I want to have two new functions in the decorator, one that returns a Transfer object for the parent record, and one that returns an array of Transfer objects representing each child record. Here's the code:

<cfcomponent displayname="itemsDecorator" extends="transfer.com.TransferDecorator" output="false">

<cffunction name="getMyParentItem" access="public" output="false" returntype="any">

<cfreturn getTransfer().get("example.Item",getTransferObject().getParentId()) />

</cffunction>

<cffunction name="getMyChildItems" access="public" output="false" returntype="array">

<cfset var local= StructNew() />

<!---Create an array to hold the child objects--->

<cfset local.childrenArray= ArrayNew(1) />

<!---Create query results of all items for whom the current item is the parent, ordered by itemOrder (defaults to asc)--->

<cfset local.childrenQry= getTransfer().listByProperty("example.Item","parentId",getTransferObject().getItemId(),"itemOrder")>

<cfoutput query="local.childrenQry">

<!---Create a TransferObject for each record and insert it into the array--->

<cfset ArrayAppend(local.childrenArray,getTransfer().get("example.Item",local.childrenQry.itemId))>

</cfoutput>

<cfreturn local.childrenArray />

</cffunction>

</cfcomponent>

In a decorator CFC that extends the TransferDecorator CFC, you can access the current item's Transfer object all of its functions via the getTransferObject() function, and you can access the main Transfer object via the getTransfer() function. So the single statement in the getMyParentItem() function in the decorator CFC is equivalent to:

<cfset parentItemObject= transfer.get("example.Item",currentItemObject.getParentId())>

The getMyChildItems() function is slightly more complicated because it needs to retrieve a recordset of child objects first, using the listByProperty() function of the main Transfer object (again, provided via the getTransfer() function within the decorator), then loop through those records, creating a Transfer object for each child record and appending it the array returned by the function.

What if the item record in question is either at the top of the item hierarchy or at the bottom? If there is no parent item, the Transfer object returned by the getMyParentItem() function will have an itemId of 0 (the default value for an empty numeric primary key) and empty values for all of the other properties, so you can test for that condition. If there are no child items, the array returned by the getMyChildItems() function will simply be empty.

This is only the second Transfer decorator I've ever written, so there may be a better way of going about it, but it gets the job done with just two short functions added on to existing object functions provided by Transfer. I like it when things are this easy.

Creating a hyperlink that works with or without AJAX

The current project I'm working on includes a display page where users can see a list of messages generated for them by the system. Each message consists of an <li> element containing the text of the message followed by a hyperlink labeled "Delete".

I wanted to make it such that you could delete each message without refreshing the page, but still accommodate users who had JavaScript turned off, and without a lot of extra work.

How did I do it? Like so:

<!---Include the jQuery core file--->
<script type="text/javascript" src="/views/JavaScript/jquery-1.2.2.js"></script>

<script language="javascript">
//Set the typical jQuery ready event handler to fire when the document is ready for manipulation
$(document).ready(function () {

//Assign a click event handler for all of the 'delete' hyperlinks (which all have a CSS class of 'deleteLink')
$(".deleteLink").click(function () {

var linkObj= $(this);
//Take the existing URL in the 'href' value and append an additional URL variable
var ajaxURL= linkObj.attr("href") + "&js=1";

//Remove the li list element (the parent) the link belongs to
linkObj.parent().remove();

//Make the Ajax call
$.ajax({
type: "POST",
url: ajaxURL
}); //end of .ajax function

//This statement will prevent the browser from actually navigating to the address in the link
return false;

}); //end of .deleteLink click function
}); //end of document.ready function
</script>


<h2>Your Messages</h2>

<ul>

<cfoutput query="qryMessages">

<li id="#messageId#">

#message#<br />
<a class="deleteLink" href="index.cfm?fuseaction=#xfa.deleteMsg#&msgId=#messageId#">Delete</a>

</li>

</cfoutput>

</ul>

...The only other thing you need to do is put a conditional statement in the page/event that is called by the hyperlink that looks for the presence of the additional URL variable ("js" in this case).

If JavaScript is turned off, that additional variable will not be defined and the page/event will redirect the action back to the calling page once it's done deleting the message data from the database.

If JavaScript is turned on, the page/event will simply delete the message data (no action redirect), and the user simply sees that message item disappear from the list.

A ColdFusion IDE feature request: tools for creating Java classes

One of the "themes" that I took away from cf.Objective() was the shortcomings of ColdFusion when it comes to generating a collection of objects. Most everyone agrees on the fact that there is a performance penalty when a CFC is translated into a Java class (or, usually, a series of Java classes) because ColdFusion is a dynamically typed language and Java is not, and reconciling that difference takes processing power.

But not everyone agrees on what the solution to this issue should be. Some folks believe that Adobe should try to improve object generation performance even more, building on the improvements that came with ColdFusion 8. Others feel certain that ColdFusion will always pale in comparison to Java when it comes to object generation and that any enterprise-level ColdFusion application should use pure Java classes on the back end. A few folks at cf.Objective() even advocated integrating ActionScript 3 (the strongly-typed programming language behind Flex) into ColdFusion for use in building objects.

Personally, I would love to see a big improvement in object performance in the next version of ColdFusion 9, but I strongly suspect that equivalent objects written in pure Java classes will still be significantly better in terms of performance despite Adobe's best efforts.

If we accept that as the most likely outcome, then the issue becomes how to get ColdFusion developers without any Java background (like myself) to code objects in Java?

I think one way of accomplishing that is for Adobe to create a ColdFusion IDE that provides ColdFusion developers with an easy means to create Java classes and use those Java classes for the model in their applications. It could provide a wizard similar to the CFC wizard tool in CFEclipse that either generates the .java file based on a database table or lets the developer manually define properties and methods for the class. It could also provide a means of generating the Java class files based on an XML configuration file so existing code generators could be modified to work with this IDE feature.

Of course, creating the .java files is only the first step. The IDE should also be able to introspect any .java file and display all of the information a developer would need to interact with that resulting class (properties, methods, data types, etc.) If the developer needs to make changes to the class, they could either edit the .java file directly in a normal IDE editor window (with syntax checking), or via an editing dialog box that lets the developer make changes to the configuration of a method and the statements within the method without having to worry about aspects of the Java syntax involved in describing the method. The IDE would also take care of compiling the .java file to a class every time it is updated and reporting back any compilation errors.

Like I said, I have no Java programming background, so maybe this idea is more than a bit of a stretch. There are also probably other issues that would need to be addressed (like how to manage the dependencies between the Java classes), but I'm betting cleverer folks than I could figure out a way to make it work. Even if the tools for creating Java classes were limited in what they could do, allowing ColdFusion developers to generate their own .java files and Java classes using familiar terms and concepts and then see the results could shorten the Java learning process.

ColdFusion has a long tradition of making it easy for developers to perform certain tasks and operations. When we talk about that tradition, we tend to narrow our focus on the capabilities of the CFML language. We tend to forget that the ColdFusion server software makes our lives easy as well, letting us configure datasources, security features, and gateway processes without having to deal with those issues in our programming code. It's the entire ColdFusion package, as a whole, that makes developing in ColdFusion easier than developing in other languages.

If Adobe develops a ColdFusion IDE, that IDE should also be designed--optimized, in fact--to make developing in ColdFusion easy, regardless of the developer's skill level. So I say if our OO ColdFusion developers need to be able to create their objects in Java, that IDE should help them do that.

ColdFusion Weekly Podcast 3.08: Andy Powell on Enterprise MVC with CF and Java

The latest version of the ColdFusion Weekly podcast was released yesterday. In this episode, Matt and Peter talk with Andy Powell about using native Java objects as the basis for your model when building your ColdFusion applications using the model-view-controller (MVC) architectural pattern. Andy gave a presentation on this topic at cf.Objective().

As always, you can get it by either subscribing to the podcast via ITunes or by downloading it from the ColdFusion Weekly web site.

A tip regarding many-to-many relationships in Transfer

Thought I should share this so no one else ends up learning it the hard way like I did yesterday.

In Transfer, you use an XML configuration file to describe your database tables and the relationships between them. You can define three types of relationships: one-to-many, many-to-one, and many-to-many.

The many-to-many relationship is used when one table is related to another table through the use of a linking table. In the introductory Transfer example files I looked at today, the many-to-many example is an application with an Events table, a Categories table, and an Events-Categories table containing a foreign key field referring back to the Events table primary key field, and a foreign key field referring back to the Categories table primary key field.

Now, when you define a one-to-many or many-to-one relationship between two tables, you describe both tables in the Transfer configuration files: they each have their own <object> XML block so Transfer objects can be created based on them. What I did not realize until today, when I looked more closely at those example Transfer files, is that you DO NOT create an <object> XML block for the linking table. The many-to-many relationship that you describe within one of other two tables' <object> block tells Transfer all it needs to know to relate the two tables.

Now, if I had read the Transfer documentation more carefully, or if I had tested my Transfer configuration file either against the included schema file or with testing code as I made changes to it, I probably would have figured this out a lot faster. But because I didn't do either of those things, I was baffled by the inscrutable and inconsistent error messages returned by my application when I started working on the CRUD operations involving those tables.

So in addition to the tip itself, my other piece of advice is to take your time and carefully read (and think about) the documentation when you start working with a new framework like Transfer: it may be easy to get started with, but you might miss a subtle detail or two that can get you in trouble.

More Entries

BlogCFC was created by Raymond Camden. This blog is running version 5.1.004.