Posts Tagged coldfusion

ColdFusion Builder : ORM code generator

If you have started using ORM (or you want to start) in ColdFusion 9, there is a nice plugin in ColdFusion builder that can help you quickly generate all the ORM code for you. All you do is select the tables from the RDS view, define the relationships, if there is any, and all the code including the service layer will be generated. Evelin talks about it here. Oh btw, if you did not notice, thats the ColdFusion Builder team blog.

You can download the plugin from here and download the instruction from here. Have Fun playing with it !!!

Tags: , ,

ColdFusion ORM and CFC Performance

Since the day we started thinking about ColdFusion ORM, people have been raising concerns over it because of the CFC performance. We have heard people saying that ORM will be unusable because of poor CFC performance and it is a stupid idea to implement CFC based ORM. And today I heard Hal Helms and Brian kotek talking about it where Hal says that he shudders at the thought of hibernate integration in CF because of poor performance.

It is true that CFC performance is poor as compared to POJO and it will always be. ColdFusion CFC has lot of cost involved because of the dyanmic nature of it and additionally, it has reflection cost involved. I had shared some of the reasons with few of the community members and I thought it will be interesting to share it with a wider audience. Here are the main reasons :

  1. Unlike java where the class has a fully qualified name and is loaded only once in the classloader, when you create CFC, CF needs to search for the CFC file on the disk, compute the class name for it and then load it. And that happens on each object creation unless you have switched on trusted cache .
  2. CFC  is compiled at runtime, loaded and constructed using reflection. I am sure you will be aware that reflection is much slower (25 times easily) than direct invocation in java.
  3. CFC has two different scopes – this and variables scope which is a struct. So every object creation involves two additional struct creation cost.
  4. CFC creation also involves running the default constructor i.e any code outside cffunction and that happens for each object creation. That involves the complete setup for method invocation i.e setting up localscope, superscope etc (another two structs here), which is also significant
  5. CFC allows UDFs to be added/removed from the object at runtime and hence methods are added to each object on object creation and that too in both the scopes (adding each UDFs in both the scopes also has significant cost). Thats the reason why object creation becomes costlier as you add methods in the CFC. Higher the number of methods, higher the object creation cost.

We have done a lot of performance improvements regarding CFC creation and invocation in ColdFusion 9 which I hope you would have noticed. But even then it can not match POJO performance and thats an unrealistic target.

So given that, lets come to the question – How much does CFC creation performance matters when it comes to ORM. In reality, not much. We have done a number of performance comparison between CFC and POJO with hibernate keeping everything else absolutely same. And all the time, CFC performance was same or better than POJO persistence. It might sound unbelievable and in fact I also could not believe it myself when I saw the performance numbers first. But that is the truth. And here is why it happens – When it comes to persistence, the time taken in DB operation and the persistence layer is much more than the time taken in object creation. And that cost is same for POJO and CFC. So the only difference in cost between CFC and POJO with respect to ORM is object creation cost and cost of populating/fetching the properties data. For instantiating POJO object and for using properties accessors, Hibernate has to use reflection which is always costly and that removes this cost difference of CFC and POJO. And for few of the runs, CFC was able to beat POJO as well and explanation for that is the optimizations that we have done in using accessors for properties.

I would be curious to know about your experience regarding CF-ORM performance and CFC performance in general. How has your experience been so far regarding CF-ORM peformance?

Tags: , ,

ColdFusion ORM : The basics

Before starting on the advanced topics, I thought it will be better to build some ground and hence I decided to do a post on the ORM basics. In this post, we will build a simple example to get a taste of ColdFusion ORM (CF-ORM) and during that we will also understand some of the basic concepts.

ORM is object relational mapping and in ColdFusion, objects are created using CFC. CFCs that needs to be persisted are called persistent CFC and that is marked by setting ‘persistent’ attribute to true on the component. We also need to define what persistent fields will be there in a persistent CFC and that is defined using ‘cfproperty’. A field/property is marked persistent by setting persistent attribute to true on the cfproperty. By default, if the CFC is persistent, all its properties are considered as persistent unless you mark a property non-persistent. So typically ‘persistent’ attribute on the property is used only when you need to make that property non-persistent.

Each persistent CFC in ColdFusion application maps to a table in the database and each property in the persistent CFC maps to a column in the table (not exactly true but we will come to that later.. For the time being lets keep it that way). We will use the cfartgallery datasource for this example which has Artists and Art tables.

The first thing you need to do is – enable ORM for the application and define a datasource to be used (What is an ORM without a datasource?). ColdFusion ORM uses Application.cfc to define all the ORM specific settings. (If you haven’t started using Application.cfc for your application, its time to start using it!)

Application.cfc

Component {
    this.name="ArtGallery";
    this.ormenabled="true";
    this.datasource="cfartgallery";
}

Note that the datasource setting defined here makes it the default datasource of your application which can be used by tags like cfquery, cfinsert, cfupdate, cfdbinfo. The same default datasource will be used by ORM as well.

There are a whole bunch of ORM related configuration that you can do in application.cfc which you can refer here.

Now that the application is configured, let us build the object and define the persistence information on it. To start with, we will first define the Artist.cfc

Artists.cfc
/**
 * @persistent
 */
Component {
    property name="artistid" generator="increment";
    property firstname;
    property lastname;   
    property address;
    property city;
    property state;
    property postalcode;
    property email;
    property phone;         
    property fax;
    property thepassword;
}

This is the most simplistic definition of the component where we have defined only the component and its properties names. Since the table for this CFC already exists in the database, we have not added any table specific information in this and we will let ORM infer all the information from the database. The only additional setting that we have added here is the ‘generator’ attribute which is used to auto-generate the primary key.

After the components are defined, the first request to this application (i.e a page in this application) will make CF-ORM do all the setup necessary (basically generation of hibernate configuration, mapping files, building the session factory etc). Once the setup is done, you are all set to work with the entities.

We will first list all the artists and here is what you need to do for that

listAll.cfm

<cfscript>
   artists = EntityLoad("Artists");
   writedump(artists);
</cfscript>

To load a particular Artists with its ID, here is what you do

 list.cfm

<cfscript>
   artist = EntityLoadByPK("Artists", 1);
   writedump(artist);
</cfscript>

There are several flavors of EntityLoad functions details of which can be read here

Let us now see how to perform insert and update on it.

save.cfm

1
2
3
4
5
6
7
8
9
10
11
<cfscript><br>   // Insert a new artist
   artist = new Artists();
   artist.setfirstname("Leonardo");
   artist.setlastname("Da vinci");
   artist.setcity("Paris");
   EntitySave(artist);
 
   writeOutput(artist.getartistid());// Update an artist
   artist = EntityLoadByPK("Artists", 2);
   artist.setcity("NewYork"); // artist is automatically updated.
</cfscript>

As we see in the above example, EntitySave is used to insert/update an object in the table. There are some important things to note here

  • EntitySave is an intelligent function which automatically finds if a new row needs to be inserted for the given object or whether an existing row needs to be updated.
  • We called EntitySave for the insert here but not for update but even then artist ‘2′ gets updated. So how did that happen? Actually what happens here is when you load an artist object, it becomes associated with the hibernate session which keeps track of any changes in the object and automatically saves it when the session is flushed. We will talk about more about hibernate session in a later post. For the time being lets just say that Hibernate Session is a short-lived object that represents a conversation between the application and the persistence layer and also acts as the first level of cache.
  • We did not write any setter or getter method for artist’s properties in Artists.cfc but we are calling them here. That works because ColdFusion 9 automatically generates accessor methods for any property written in a CFC. More details on generated methods in a later post.
  • At line no 6, we called entitySave, but if you check the database, the row is not inserted yet. So when does that happen? Hibernate batches up all the operations till the end of the request or to be exact till hibernate session is flushed. ColdFusion ORM starts up a session when the first ORM method is called in the request and is automatically flushed when the request ends. The batching is done for performance reason so that hibernate executes the sql with the final state of the objects. It will be a huge performance bottleneck if ORM keeps executing sql for each changes in the object.

To delete an Artist, you need to call EntityDelete() passing the object to be deleted.

delete.cfm

<cfscript>
    artist = EntityLoadByPK("Artists", 15, true);
    EntityDelete(artist);
</cfscript>

Relationship

So far we have seen how to perform CRUD for a single entity. But in any application, there will be entities which are associated and ORM must load the associated object as well when loading a particular entity. For our example, an Art will have an Artist and when loading the art object, it should also load the associated artist. So lets build the model first after which we will see how to work with the association.

In cfartgallery, the table Artists has a one-to-many relationship with Art table, which are joined using the foreign key column ARTISTSID. This means that each artist has created multiple arts and each art is created by one artist. To represent this in the object model, each ARTIST object would contain an array of ART objects. Each ART object will also contain a reference to its ARTIST object thereby forming a bidirectional relation.

To achieve this, we will need to add an extra property ‘arts’ to ‘Artists’ that contains an array of ART objects for that Artist. The modified Artists.cfc would look like

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
 * @persistent
 */
Component {
    property name="artistid" generator="increment";
    property firstname;
    property lastname;   
    property address;
    property city;
    property state;
    property postalcode;
    property email;
    property phone;         
    property fax;
    property thepassword;
    property name="arts" fieldtype="one-to-many" fkcolumn="artistid" cfc="Art" cascade="all" inverse="true";
}

Here is the Art.cfc

1
2
3
4
5
6
7
8
9
10
11
12
/**
 * @persistent
 */
Component {
    property name="artid" generator="increment";
    property artname;
    property price;
    property largeimage;
    property mediaid;
    property issold;
    property name="artist" fieldtype="many-to-one" fkcolumn="artistid" cfc="Artists" ;
}

Notice the artist property above which is of many-to-one type. Also notice that both the property use the same value for fkcolumn attribute i.e ‘artistid’ of Art table that references artistID pk of Artist table.

Since we have added a new persistent CFC (Art.cfc) after the application was loaded, we need to re-initialize the ORM for this application so that mappings for Art.cfc also gets generated. This can be done by calling ORMReload() method. There are some nice ways to do this but for the time being lets keep it simple by putting this in a separate page which we will call to reload ORM.

initializeORM.cfm

<cfset ormReload()>

If you load and dump Artist (using listAll.cfm), you should also see the associated art objects for artists.

Now let us create a new Art and associate it with an existing Artist.

artCreate.cfm

1
2
3
4
5
6
7
8
9
10
<cfscript>
    artist = EntityLoad("artists", 1 ,"true");
    art = new Art();
    art.setartname("landscape");
    art.setPrice(1500);
    art.setissold(false);
    art.setartist(artist);
    artist.addArts(art);
    EntitySave(art);
</cfscript>

If you notice line 7-8 above, we associate artist to art by calling art.setArtist(artist) as well as art to artist by calling artist.addArts(art). Hibernate needs us to do this in order to set up the bidirectional relation properly. Since it is a bidirectional relation, you must also decide which side will set the relation in the database. i.e which side of the relation will set the fkcolumn in the table. This is controlled by the “inverse” attribute of proeprty, which if set to true, tells hibernate that this is a inverse of the other relation and this side of relation should be ignored for persistance. If you don’t set inverse to true, Hibernate will unnecessarily fire two sqls for the same association.

So there you have it. We have seen how you can use ORM to perform the basic CRUD operations on entities. For more details, you can refer to the ORM doc and Hibernate docs.

Tags: , , ,

ColdFusion ORM – An Evolution in building datacentric application

As we all know, ColdFusion was born as DBML – a script that was very similar to HTML but had certain tags that could perform database operation and it revolutionized the way web applications were built. Tags like cfquery, cfinsert, cfupdate made it very easy to perform database operations while building web application. Even after 14 years of CFML, (which we incidently completed day before yesterday), cfquery is *the* most popular and the most commonly used tag. However there are few downsides to it

  • Database vendor dependency – The queries that are written are DB specific. If you ever need to switch the database or if you need to make the application database agnostic, it becomes too much of pain. You will end up changing the entire application code or lot of conditional code to handle queries for different databases.
  • Very tight coupling with the database – The queries have very tight coupling with the database. This means that if there is any change in the table name or column name, you will end up with changes all over your application code.
  • Repititive and hence low on productivity – For any CRUD (Create, read, update and delete) operation, you need to write queries which are more or less same for all the tables. You must have felt that you are repeating the same code everywhere in the application. There is too much of repititiveness which reduces productivity.
  • Error prone – How many times did you write insert/update queries and then you had to struggle to debug because the order of column and its values were different? And how many times did you get frustrated because there was a datatype mismatch between the value you had specified and the one expected? How many times did you write a query that was prone to sql injection and you were reminded to use query param? I am sure all of this has happened to all of us and its completely natural given the way queries are written. They are error prone.

ColdFusion 9 introduces a new way to build datacentric application using ORM, that handles all the downsides we saw above. It is not a replacement to cfquery/cfinsert/cfupdate tags but its a different approach altogether. It allows you to build your application using objects where you focus on the business logic and all the grunt work of persistence is taken care automatically (In simple words you dont write SQL queries generally).

ORM (Object relational mapping) is a well known strategy/technique to map relational data to the object model. In an object model, business objects are not aware of the database structure. Objects have properties and references to other objects whereas Databases consist of tables with columns that are related to other tables using foreign key. ORM provides a bridge between the relational database and the object model allowing you to access and update data entirely using the object model of an application.

ORM is not new to ColdFusion either – Transfer and Reactor being the most popular ones. ColdFusion ORM (or CF-ORM) is much more extensive and sophisticated ORM solution than these ORMs. ColdFusion ORM is built on top of Hibernate – the best java ORM engine out there, which is quite powerful and extensive. ColdFusion ORM makes it very easy to use persistence with objects and at the same time allows you to leverage the full power of Hibernate.

ColdFusion ORM provides features such as

  • Defining the persistence mapping and managing the object’s persistence using very simple methods.
  • Database vendor independence
  • Loose coupling between database and application – The application becomes very adaptive to changes as the configuration is central and changes will be required only there.
  • Auto-generation of schema – ORM lets you auto-generate the schema for your application. So you never need to bother about keeping your object model and the database schema in sync. It can automatically happen.
  • Productivity and manageability – Since ORM takes care of all persistence grunt work, you focus on your application logic and thus your application becomes much more cleaner and manageable. It also makes you lot more productive as application can be built much more faster.
  • Concurrency – ORM inherently takes care of concurrency control. So you dont need to worry much about how things would work when multiple database operations happen in parallel web requests.
  • Performance – ORM provides lot of performance optimizations that can make your application run faster. The optimizations include two levels of caching (including pluggable distributed cache), lazy loading, various settings to tune the sql queries generated by ORM.
  • Secure – Since queries will be executed by ORM, issues like SQL injection no longer exist and thus your application becomes secure.
  • Inbuilt pagination
  • SQL like query (HQL) for a finer control of the data to be loaded.

In this series of posts, I will be talking lot more about ORM which I hope you would like. In case you have not downloaded ColdFusion 9 beta, go download it and start playing with it.

Tags: , ,

ColdFusion 9 and ColdFusion builder beta available

I am sure by the time you will be reading this, the blogosphere will be buzzing with this news :-) . We just (13th July 12:01 AM EST) went live with the beta of ColdFusion 9 and ColdFusion builder. All of us in the team had been working really hard for last one and half years to put in features, that will take RAD to the next level, features that will make your life easy, features that you are going to love. ColdFusion has always been known for “making hard things easy” and I am sure this release will make even harder things easy :-)

Ben talked about the new features in ColdFusion 9 and ColdFusion beta here :

http://www.adobe.com/devnet/coldfusion/articles/coldfusion9_whatsnew.html

http://www.adobe.com/devnet/coldfusion/articles/cfbuilder_whatsnew.html

Here are the links for public beta

ColdFusion 9 : http://labs.adobe.com/technologies/coldfusion9/

ColdFusion Builder : http://labs.adobe.com/technologies/coldfusionbuilder/

I also wanted to highlight an excellent devnet article written by Mark Mandel introducing ColdFusion ORM. I am sure ColdFusion ORM is going to completely change the way ColdFusion applications are built and is going to make you much more productive. Hey, I am not boasting because its my baby, but I genuinely feel this :-)

Tags: ,

New ‘EvalAtPrint’ attribute in CFDocumentItem

A new evalAtPrint attribute has been added to cfdocumentitem tag in ColdFusion 801 which is applicable when the item type is header or footer. The default value of this attribute is false.

Note: The cfdocumentitem behavior with the default evalAtPrint value is identical to the behavior in ColdFusion MX 7, but differs from the behavior of the ColdFusion 8 release.

When the evalAtPrint attribute value is false, the default value, ColdFusion evaluates the cfdocumentitem tag body at the same time when it is processing the cfdocument tag. This is the behavior identical to CFMX7. In this case you can use CFDocument variables (TotalPageCount, CurrentPageNumber, TotalSectionpageCount and CurrentSectionpageNumber) only inside cfoutput and not in any expression because the page numbers are not known unless the cfdocument body content is evaluated and layed out.

In order to use CFDocument variables in expression inside CFDocumentItem tagbody, you should set evalAtPrint to true as shown in the following example.

<cfdocument format="pdf">
<cfdocumentitem type="header" evalAtPrint="true">
       <cfif (CFDocument.currentPageNumber % 2 eq 0)>
           <cfoutput> Page is even</cfoutput>
       <cfelse>
           <cfoutput> Page is odd</cfoutput>
       </cfif>
   </cfdocumentitem >
   Document body…
</cfdocument>

In this case, ColdFusion evaluates the cfdocumentitem tag body when it prints the header or footer, not when it evaluates the cfdocument tag body. This ensures that the cfdocument tag body is already evaluated and layed out and page number information is available when cfdocumentitem tag is being evaluated

A side effect of this is, if a variable is used inside both cfdocument and cfdocumentitem, cfdocumentitem tag will only see the final value of that variable. In the following example, cfdocumentitem will always get 11 as value of ‘I’ and hence all the headers will print ‘Chapter 11’.

<cfdocument format="pdf" >
<cfloop from=1 to=10 index="i">
   <cfdocumentsection>
   <cfdocumentitem type="header" >
       <cfoutput>Chapter #i#</cfoutput>
   </cfdocumentitem >
DocumentSection body
   </cfdocumentsection>
</cfloop>
</cfdocument>

To handle this, you can now pass the variable into the cfdocumentitem tag as a custom attribute, as shown in the following example:

<cfdocument format="pdf" >
   <strong><cfloop from=1 to=10 index="i"></strong>
       <cfdocumentsection>
           <strong><cfdocumentitem type="header" evalAtPrint="true" no = #i#>
               <cfoutput>Chapter #attributes.no#</cfoutput> </strong>
               <cfif (CFDocument.currentPageNumber % 2 eq 0)>
                   <cfoutput> Page is even</cfoutput>
               <cfelse>
                   <cfoutput> Page is odd</cfoutput>
               </cfif>
           </cfdocumentitem >
           Document Body.
       </cfdocumentsection>
   </cfloop>
</cfdocument>

Tags: ,

CFUnited Presentation – All about CFThread

I did a presentation on "All about CFThread" at CFUnited this year and I think it went fairly well. It was a repeat session – once on friday 21st June and another on Saturday 22nd June and both the sessions had pretty good number of people attending it. Thanks a lot to all those attended. As promised, I have uploaded my presentation and the sample code up here.

Please feel free to ask me questions if you have any.

Tags: ,

Reading Flash (Swf) metadata from ColdFusion

Wouldn’t it be cool if you could read the meta-data of Swf file in ColdFusion? The most common use case I can think of is to find the dimension of swf movie so that you can set the dimension for the same in object tag while you are embedding the flash movie in your page. And the good news is that you can do that currently in ColdFusion with just 2-3 lines of code!! All you need to do is to create a TagDecoder and decoder the header with it. Here is the complete code.

<cfscript>
  fis = createObject("java", "java.io.FileInputStream").init("C:\test.swf");
 // Create the FileInputStream
  decoder = createObject("java", "macromedia.swf.TagDecoder").init(fis);
 // create TagDecoder
 header = decoder.decodeHeader(); 
// Decode the header.
fis.close(); 
rect = header.size;
WriteOutput("
    Is Compressed : #header.compressed#<br>
    Frame Count : #header.framecount#<br>
    Frame rate : #header.rate#<br>
    Version : #header.version#<br>
    Height : #rect.getHeight()#<br>
    Width : #rect.getWidth()#");
</cfscript>

The height and width value that you see here would be in twips which is defined as 1/20 of a point or 1/1440 inch. This means, for a 72 dpi screeen, you will have to divide it by 20 to get the height and width in pixels.

Tags: ,

DNS lookup Caching in ColdFusion/Java

Two days back, I got an interesting question from our support team. The Customer in this case was using CFLdap which connected to a particular LDAP server and things were working fine. The problem came when they replaced this LDAP server with another LDAP server and assigned the same dns name to the new ldap server. Ideally any connection made henceforth should have worked with the new ldap server but actually that did not happen. ColdFusion started throwing error and it did not work until the ColdFusion server is restarted. Ever seen something similar?

It is obvious that it happend because the IP address was being cached for the host name as a result of which ColdFusion was still trying to connect to the old IP address even though the host name now pointed to a different IP address. This caching also applies for all other network protocol tags such as CFHTTP, CFFTP, CFFEED etc and is not limited to CFLDAP. It is actually the JVM that does this caching. When JVM is requested to resolve a host name, it does the host name to IP address resolution and caches the result. This result will be used for all subsequent lookups. It also caches the negative results. By that I mean, if the dns reolution fails, it caches the failed result for a certain period so that any lookup for that hostname in that period will not result into another resolution on network and will immediately return the failed result.

For more detail on this caching, check out the Javadoc for InetAddress class.

As per this doc, there are two parameters that control this caching

networkaddress.cache.ttl (default: -1) : Indicates the caching policy for successful name lookups from the name service. The value is specified as as integer to indicate the number of seconds to cache the successful lookup.A value of -1 indicates “cache forever”.

networkaddress.cache.negative.ttl (default: 10) : Indicates the caching policy for un-successful name lookups from the name service. The value is specified as as integer to indicate the number of seconds to cache the failure for un-successful lookups.A value of 0 indicates “never cache”. A value of -1 indicates “cache forever”.

Now where do you specify this settying? You can specify this setting in <Java_home>/jre/lib/security/java.security file. For standalone ColdFusion server it will be in <ColdFusion _dir>/runtime/jre/lib/security/java.security file.

As you see, by default networkaddress.cache.ttl caches the result for ever and hence it is configured for best performance. Any change to this mean drop in performance. If you don’t want to cache the resolved IP address for ever, as is the case here, you would need to change networkaddress.cache.ttl value to 60 seconds or 300 seconds or any value you feel suitable. You would not want to set it to 0 as that would mean “never cache” the result which might affect the performance significantly.

In which case you would want to change the value for networkaddress.cache.negative.ttl? That would be mostly in case when you want to cache the negative result for a longer time and in turn improving the performance. For example, if you are trying to connect to a hostname which can not be resolved to any ip address, and that happens very frequently, each of the call (as long as they are not in the same 10 sec window) would become very slow. Increasing this value would increase the performance but again you would not want to cache the negative result for ever.

After you change this setting, you will have to restart the ColdFusion server for this change to take effect.

Tags: , ,

ColdFusion 8 finalist among Dr. Dobb’s Jolt Product Excellence Awards

Good to see ColdFusion 8 as a finalist in Web Development tools category among Dr. Dobb’s 18th Annual Jolt Product Excellence Awards. Here is the entire story and here is the list of finalists.

Tags: ,