3
votes

Is it possible to re-use ColdFusion ORM objects across applications?

For example, I set up an ORM-enabled application named app1 in a folder named app1. I created a department.cfc that corresponds to a department database table:

<cfcomponent>
<cfset this.name = "app1"> 
<cfset this.ormenabled = "true">
<cfset this.ormSettings = {
    datasource = "myDS",
    schema = "mySchema",
    dialect = "Oracle10g",
    logSQL = "false"
}>

I can load and dump the contents from a CFM file:

<cfset item = EntityLoad("department")>
<cfdump var="#item#">

Then I set up an identical ORM-enabled application named app2 in a folder named app2. I created a department.cfc there that extends the department.cfc in app1:

<cfcomponent persistent="true" extends="my.path.app1.department">
</cfcomponent>

When I try to load and dump the contents, I get an error:

The system has attempted to use an undefined value, which usually indicates a programming error, either in your code or some system code. Null Pointers are another name for undefined values.

I have verified that the path is correct. E.g. I was able to instantiate the object using CreateObject:

<cfset item = CreateObject("component","my.path.app1.department")>
<cfdump var = "#item#">

I am hoping that I can refer to a single CFC and re-use the object, but unless I'm missing something it looks like it may be necessary to recreate the object in app2.

2
Are you trying to fetch the same instance or just instantiate the same cfc? In either case you cannot reuse the same entity within a separate application from an ORM perspective without defining the entity' metadata within both applications. You could have a library that does this and extends application.cfc while using the same datasource/entity mappings etc. - AlexP
I'm trying to instantiate the same CFC, as I thought it would be redundant to have multiple CFCs with identical code. I like your idea of an ORM library app--I will give that a try. - cherdt

2 Answers

1
votes

The CFC (entity) can be instantiated within two distinct applications where they each use their own ORM. All you need to do is place the them in this central location on the server and perhaps create an application specific/global file mapping and you can then create new instances. The most convenient way however would be via the "this.ormSettings" variable within your application.cfc as you can do it all in one place.

for instance:

    component displayname="Application"
    {
        this.ormSettings = {
            cfclocation = [
                "/full/path/to/cfc/directory", 
                "Entity",
                "/a/relative/path" 
            ]
        };

        this.mappings["/Entity"] = "full/dir/path/to/another/cfc/directory/called/whatever";

    }

Each of these locations will be searched for a matching CFC before any other directories, so there is also a potential performance benefit by defining them explicitly.

0
votes

You can certainly have multiple applications use the same "model", or set of ORM entity CFCs by having them accessible via a mapping as AlexP says.

But inheritance works a bit differently in ORM. A persistent CFC cannot extend another persistent CFC (at least not in CF9). Instead the parent CFC must be marked as a "mappedsuperclass" and the persistent attribute set to false or removed. The child persistent CFC should then be able to extend it:

<cfcomponent name="Pet" mappedSuperClass="true" persistent="false">
...
</cfcomponent>

<cfcomponent name="Cat" extends="Pet" persistent="true" table="cats">
...
</cfcomponent>

This obviously limits what you can do with inheritance in ORM. You can't use Pet as an entity in its own right, but it's useful for sharing properties that would otherwise be duplicated in your Cat, Dog and Rabbit entities.