entity init()
method must not have required argument(s), otherwise EntityNew()
and other CF-ORM actions will break. You may want to use a Factory to create the entity, and enforce the required arguments there.
A bug regarding this limitation has been filed in the Adobe Bugbase.
ORMReload()
with ormsettings.dbcreate = "drop create"
might not drop all tables for you. CF9 Cumulative Hot Fix 1 improves this a little bit, but you might want to drop the tables in DB yourself.
type="date"
(default to use ormtype="date"
), will only store date but not time. If you want to persisted time as well, use ormtype="timestamp"
type="string"
will default to varchar(255)
type="numeric"
will default to float
, not int
. Use ormtype="int" if needed.
if fieldtype="id"
and generator is set to some generator, ormtype will default to int
.
type="string" length="10"
will use varchar(10)
, not char(10)
ormtype="char" length="10"
will use char(1)
still. Use sqltype="char(10)"
if you really need to.
type="boolean"
use tinyint
by default, use sqltype="bit"
if you need to.
should use inverse=true
in a bi-directional relationship, usually in "one-to-many" side.
do NOT use inverse="true"
in uni-directional relationship! The relationship might not be persisted at all!
If you use MS-SQL, you cannot have more than 1 entity with one-to-one property set to Null, because Null is considered as an unique value in an index. Good idea to make column not null. (or use linktable)
EntityLoad("entity", 1, true)
works, but EntityLoadByPK("entity", 1)
is cleaner!
EntityLoad()
, EntityLoadByPK()
, and ORMExecuteQuery
with unique=true
, will return null
if entity is not found. Use isNull()
to check before you use the returned value.
ORMExecuteQuery
will return empty array if no entity is found by default.
don't forget to use singularname
property in "one-to-many" / "many-to-many" for nicer looking generated functions (e.g. addDog(Dog dog)
vs addDogs(Dog dogs)
.)
<cfdump>
will load all the lazy-load properties. Alternatively you may try <cfdump var="#entityToQuery([entity])#">
or set top=1 to dump efficiently.
entity stored in Session scope will be disconnected with its Hibernate session scope, and lazy load property will not be loaded. To restore the hibernate session scope, use entityLoadByExample()
or entitySave(entity)
.
cascade="all-delete-orphan"
usually make more sense for "one-to-many" or "many-to-many" relationship. Hibernate sets null then delete, so make sure the column is nullable. Test and see if that's your desire behaviour.
set required="true"
whenever notnull="true"
, more readable for others browsing the CFC with CFCExplorer
EntityNew('Y')
is slightly more efficient than new com.X.Y
if the entity is to be persisted later according to some Adobe engineer.
relationship with an inherited entity may break sometimes due to an unfixed Hibernate bug, use linktable
as a workaround.
structKeyColumn
cannot be the PK of the target entity.
bi-directional many-to-many cannot use struct
When adding new entity to struct, structKeyColumn
is ignored when CF persists the parent entity.
If you access the one-to-many / many-to-many array or struct directly, make sure the corresponding array/struct exists before use. Generated addX()/hasX()/removeX() are safe to use anytime.
at postInsert()
, the entity hibernate session is no longer available, so setting property at postInsert() will be silently ignore, or Session is Closed exception will be thrown.
after entity is loaded by entityLoad()
or HQL from DB, the changes will be automatically persisted even if EntitySave()
is not called.
transaction with CF-ORM is implemented in a way that it starts a new session and close when it's done.
inside the event (i.e. preLoad() / postInsert()), assigning to variables might throw Java exception about types. Use JavaCast() to work around the bug.
Best Answer
set
<cffile>
upload path to a web accessible, CF-enabled directory!!!isStruct()
beforeisObject()
in a series of<cfif>
's expecting isStruct only catches struct (cfc component returns True from isStruct() as well)no
HtmlEditFormat()
when displaying user-generated content (XSS)forgot to add output=false on CFC methods
not using
<cfqueryparam>
inside<cfquery>
not scoping not-so-evident variables like cfquery name or loop index in a method
use
<cfform>
when all they need is plain-vanilla HTML<form>
forgot to
UrlEncodedFormat()
user-defined URLuse
<cffeed>
without sanitizing the contenttrust
isDate()
too much (any number would return true)expect string comparison to be case-sensitive (IS and EQ operators are case-insensitive)
sending strings "yes" or "no" to
SerializeJSON()
without appending a whitespace to preserve the string (otherwiseSerializeJSON()
orDeserializeJSON()
will translate them to "true" and "false")not putting singletons services in application scope
blindly create as much CFCs as one wants like one would do in JAVA
putting complex value/object into a list (can't, list is just a string of comma-seperated values)
writing functions that takes array as an argument and modify that array expecting that array will be modified (array in CFML is passed by value)
blindly changes
access="remote"
on a method and expect it to work (when remote proxy is generally more appropriate)use a lot of WriteOutput() in cfscript when CFML is more appropriate
blindly uses
IsDefined()
whenStructKeyExists()
can generally do it more efficientlyblindly uses
Iif()
andDe()
without knowing they're as nasty as Evaluate()update some code in onApplicationStart() and not seeing the difference on refresh (restart the app!)
<cfloop>
or '' outside of<cfquery>
causing multiple new query connections to be opened. 99% of the time it's better to have multiple statements inside of one cfquery to perform multiple actions, or to UNION data together.hardcoding absolute path when
ExpandPath()
is generally betterforgot to turn on Unicode support in DSN (Unicode becomes '????')
not upgrading to the latest JRE and Hotfixes
misusing Client scope and blow up Windows registry...
uses depreciated/obsolete functions/features (i.e. flash form aka flex 1.x alpha, cftable, Verity full-text search, etc...)
passing
CFCATCH
to a function as argument typeStruct
(CFCATCH
behaves like aStruct
, but it is not. Just pass it as type 'Any
').Not reading CFC Best Practices from ColdBox wiki.
buying in the mindset of .ASP(X) or .JSP or [insert web technology] are always better.. ;)
not use
PrecisionEvaluate()
and getting all sort of floating point rounding error especially when calculating money.