I'm trying to implement CF10 ORM to a current project but there seems to be a problem between my DAO and my table (11g).
I pass in a bean in the call to this DAO method:
<cffunction name="saveData" access="public" returntype="void">
<cfargument name="DataBean" />
<cfset entitySave(arguments.DataBean)/>
</cffunction>
This should write it to the table. If I dump the arguments from inside this method the bean is populated, but nothing writes. There's no errors being thrown so nothing immediately obvious.
Can anyone tell me where I might be going wrong?
Related
I use the onError function inside Application.cfc to integrate with RayGun when the code is on live but when we are on dev I'd like to be able to revert back to the normal ColdFusion error event. At the moment I have some basic error handling in place but it isn't as good as the default ColdFusion behavior. Does anybody know if this is possible and how?
I intend to add this as a feature request for ColdFusion 12 if there is no way of doing it.
This works when I run it.
in Application.cfc
<cffunction name="onError" access="public" returntype="void">
<cfargument name="Exception" required=true type="any">
<cfif true>
<cfthrow object="#arguments.exception#">
<cfelse>
error
</cfif>
</cffunction>
in cfm page.
<cfscript>
X=Y; // Y is undefined
</cfscript>
All you have to do is replace <cfif true> with something that identifies your development environment.
I am looking into ORM and started off with some tutorials from a pdf that I found on adobe's site. I created a folder under wwwroot called test.
here is my application.cfc
component {
this.name = "artGalleryApp" ;
this.ormenabled = true ;
this.datasource = "cfartgallery" ;
}
I have artists.cfc under wwwroot/test/model folder.
<cfcomponent persistent="yes" table="artists" entityname="giggidy">
<cfproperty name="id" column = "artistID" generator="increment">
<cfproperty name="firstName">
<cfproperty name="lastName">
<cfproperty name="address">
<cfproperty name="city">
<cfproperty name="state">
<cfproperty name="postalCode">
<cfproperty name="email">
<cfproperty name="phone">
<cfproperty name="fax">
<cfproperty name="thePassword">
</cfcomponent>
Then, I have an index.cfm with the following:
artists = EntityLoad("ARTISTS") ;
writeDump(artists) ;
When I run this, I get :
Mapping for component ARTISTS not found.
Either the mapping for this component is missing or the application must be restarted to generate the mapping.
I restarted CF application server, and this error went away. Do I have to restart CF appliction server every single time I create an ORM application?
Is it better to use model.ARTISTS or some other way to specify where this component is located?
Now, the biggest question. I always wrote stored procedures, packages, etc etc(SQL Server, Oracle) whenever I needed DML statements. I never included inline queries in my CF code. I also handled logging and error handling within these procs, packages, etc. etc.
If I had to make a change to the database structure, I would simply modify things on the database side. For this reason only, what would be the benefits of using ORM? I change a table add/remove a field, I have to go through CF code to make the necessary updates. Why?
Mapping for component ARTISTS not found because: entityname="giggidy"
so use EntityLoad("giggidy")
And use ORMReload() and you don't need to restart CF.
I've started using ORM in Coldfusion 9, but I'm running into an issue in which I've got a CFC that is set to persistant=true so that when I run myCFC.init() the default values of the properties are assigned - but I don't want to use this CFC with ORM.
The problem is that Coldfusion throws the error "Table myCFC defined for cfc myCFC does not exist."
Is there a way I can get my application to ignore certain CFCs? Or only pay attention to specific CFCs, other than persistant=true
Alternatively, can I get my default property values to take effect without making the component persistent
Alternatively, can I get my default property values to take effect without making the component persistent?
Yes, just set them in your init() method.
<cfcomponent name="person" persistent="false" output="false">
<cfproperty name="gender"><!--- Non-persistent CFC: you can't set a default here --->
<cffunction name="init" output="false>
<cfset variables.gender = "m"><!--- Set the default here --->
</cffunction>
</cfcomponent>
You would also need to do this in your persistent CFCs for any complex or dynamic value defaults (e.g. an array or the current date), since you can only set simple default values (e.g. a literal string or integer) in property declarations.
<cfcomponent name="person" persistent="true" table="persons" output="false">
<cfproperty name="gender" default="m"><!---Persistent CFC, so this simple default will be set --->
<cfproperty name="dateCreated"><!---You can't set a default dynamic date value --->
<cffunction name="init" output="false>
<cfset variables.dateCreated= Now()><!--- Set the current datetime here --->
</cffunction>
</cfcomponent>
Any code you place between your opening and the first will be executed. I'm assuming your using CFproperty tags to set you defaults. Instead, use this structure:
<cfcomponent name="aCFC">
<!---
|| Psuedo Constructor code: this code runs when the object is created.
||--->
<cfset defaultVar_1 = "default value">
...etc
<cffunction name="firstFunction">
...
</cffunction>
</cfcomponent>
I'm trying to setup my first application.cfc file.
I tried to invoke variables on an "event-basis" like so:
<cffunction name="onApplicationStart" returnType="boolean" output="false">
<cfparam name="Application.RootDir" default="/">
<cfreturn true>
</cffunction>
<cffunction name="onSessionStart" returnType="boolean" output="false">
<cfparam name="Session.activeSession" default="Yes">
<cfparam name="Session.activeLogin" default="No">
<cfreturn true>
</cffunction>
I thought this would work nicely, but turns out, it does not, because I need to declare everything before, like so:
<cfparam name="Application.RootDir" default="">
<cfparam name="Session.activeSession" default="">
<cfparam name="Session.activeLogin" default="">
My Question:
Why should I use CF-events for declaring variables. If I need to declare outside of an event anyway, I could save myself a line of code and declare&assign the inital value? Am I doing it wrong or are events only for assinging not for declaring?
Thanks for input!
What do you mean by "before" ("declare everything before")? Before what? The onApplicationStart() handler is the first thing run when an application starts, and the onSessionStart() handler is the first thing run when a session starts. So in the context of applications and sessions being established, there is no "before". I think you need to show us more code: eg some code that demonstrates them "not working".
That said, you don't show us the pseudo-constructor section of your Application.cfc, so it's impossible to tell what problems you have there, if any. But you need to enable session management before sessions will work, and you possible need to name your app before either application or session variables will stick, too (although they might just work with the nameless application too? Even if they do, it's best to name your app).
Lastly - and this will have no bearing on whether your variables are set or not, but you should be using <cfset> when setting variables, not <cfparam>. Both have the same effect here, but the former is the correct tool for the job.
Via this question I've been told to start using cfqueryparam for my data, to prevent SQL injection attacks.
How do I use it for my forms? Right now I've been going over Ben Forta's book, Vol 1 and been passing data to my form, then to a form processor that calls a CFC. The CFC takes them in as a cfargument then injects that into the database with any type="x" validation.
Io use the cfqueryparam, I use that on the query itself and not even declare cfargument?
You can still use a CFC, but remember that string data passed as a function argument will still need <cfqueryparam>. Here is an example:
<cffunction name="saveData" access="public" returntype="void" output="false">
<cfargument name="formVar" type="string" required="true" />
<cfquery name="LOCAL.qSave" datasource="myDSN">
insert into myTable (col1)
values (<cfqueryparam cfsqltype="cf_sql_varchar" value="#ARGUMENTS.formVar#" />)
</cfquery>
</cffunction>
The important habit to get into is to always use <cfqueryparam>, even in CFCs.
Here is some more info on those edge-cases where you might find it hard to use <cfqueryparam>.
Hope that helps!