Reputation: 627
The following is running on a ColdFusion 2018 server (in the event this is a version-specific issue).
I'm setting the Application datasource property in the onApplicationStart() LifeCycle Handler, but the datasource property isn't accessible in a CFM Template.
I'm thinking it may have something to do with how the this
Scope is handled inside the onApplicationStart() method, but I'm not certain. I tried setting the datasource property using this.datasource
as well as Application.datasource
, but it's not accessible in the CFM Template either way.
Application.cfc
// The usual App config stuff here... (omitted for brevity)
// Instantiate Instance of Java System Object used to set System Env Vars
this.System = createObject("java", "java.lang.System");
// Include Config files
include "resources/config/AppSettings.cfm";
include "resources/config/onApplicationStart.cfm";
AppSettings.cfm
if (! isDefined(this.System.getProperty("DB_DSN_CREATED")))
{
// Code to read values from .env file here ... (omitted for brevity)
// Set System Env Vars
this.System.setProperty("DB_USER_NAME", "DB USERNAME FROM .ENV FILE HERE");
this.System.setProperty("DB_USER_PASSWORD", "DB PASSWORD FROM .ENV FILE HERE");
}
onApplicationStart.cfm
if (! isDefined(this.System.getProperty("DB_DSN_CREATED")))
{
this.datasources = {MY_DSN = { PROPS FOR DB CONNECTION HERE }};
// *** NOTE: This is the Property that isn't accessible in the CFM Template
// I also tried Application.datasource, but that didn't work either
this.datasource = "MY_DSN";
this.System.setProperty("DB_DSN_CREATED", true);
}
db-test.cfm
<cfscript>
variables.appInstance = createObject('component', 'Application');
variables.sql = "SQL STATEMENT HERE";
variables.sqlParams = {};
// *** NOTE: variables.appInstance.datasource below isn't accessible
// I also tried Application.datasource but that didn't work either
variables.sqlResult = queryExecute(variables.sql, variables.sqlParams, {datasource = variables.appInstance.datasource});
writeDump(variables.sqlResult);
</cfscript>
Does anyone see what I'm missing? Thanks in advance for any guidance!
Upvotes: 2
Views: 503
Reputation: 6550
Thinking on this some more, I suspect you may be misunderstanding how an Application.cfc's this
scope operates. Short answer: this
isn't persistent, like the application
scope, because the component gets instantiated on every request
From Defining the application and its event handlers in Application.cfc
When ColdFusion receives a request, it instantiates the Application CFC and runs the Application.cfc code ...
Your code actually does work. At least in the sense that the include
successfully changes the value of this.datasource
when invoked. However, since the Application.cfc gets instantiated anew on every request, the component's this
scope also gets recreated. Essentially wiping out any previous changes made inside OnApplicationStart()
. That's why it seems like the code never assigns a datasource value, when it actually does.
Bottom line, an Application.cfc's this
scope isn't intended to be used that way.
FWIW, you can see the behavior in action using the test files below. Just load test.cfm
in a browser (at least twice) then check the logs. The output shows a value IS assigned to this.datasource
the very first time test.cfm is requested from the application. However, that value disappears on the next http request because CF creates a new Application.cfc instance.
Application.cfc
component
{
this.name = "myApp_0001";
function onApplicationStart(){
writeLog("onApplicationStart()");
writeLog(serializeJSON({"name": this.name, "datasource": this?.datasource?: "" }));
include "onApplicationStart.cfm";
}
function onRequestStart( string targetPage ) {
writeLog("onRequestStart()");
writeLog(serializeJSON({"name": this.name, "datasource": this?.datasource?: "" }));
}
}
OnApplicationStart.cfm
<cfscript>
writeLog("onApplicationStart.cfm");
writeLog(serializeJSON({"name": this.name, "datasource": this?.datasource?: "" }));
writeLog("Assigning this.datasource");
this.datasource = "MY_DSN";
writeLog("Post Assign this.datasource");
writeLog(serializeJSON({"name": this.name, "datasource": this?.datasource?: "" }));
</cfscript>
test.cfm
<h3>Test.cfm <cfoutput>#now()#</cfoutput></h3>
Results:
Request #1 - this.Datasource gets assigned
[INFO ] ... - onApplicationStart()
[INFO ] ... - {""datasource"":"""",""name"":""myApp_0001""}
[INFO ] ... - onApplicationStart.cfm
[INFO ] ... - {""datasource"":"""",""name"":""myApp_0001""}
[INFO ] ... - Assigning this.datasource
[INFO ] ... - Post Assign this.datasource
[INFO ] ... - {""datasource"":""MY_DSN"",""name"":""myApp_0001""}
[INFO ] ... - onRequestStart()
[INFO ] ... - {""datasource"":""MY_DSN"",""name"":""myApp_0001""}
Request #2 - this.datasource is no longer assigned
[INFO ] ... - onRequestStart()
[INFO ] ... - {""datasource"":"""",""name"":""myApp_0001""}
Request #3 - this.datasource is no longer assigned
[INFO ] ... - onRequestStart()
[INFO ] ... - {""datasource"":"""",""name"":""myApp_0001""}
Upvotes: 2