I've been using Hibernate for a while now in Java / Groovy projects, but I tend to not use it directly from my service layer. Instead, I've found it simpler / more testable / more portable to still use the DAO pattern, wrapping Hibernate functionality. Instead of the tedious process of writing tons of DAOs, though, I write a "generic" DAO, implementing domain-object specific methods as needed.
I've cooked up a similar DAO for use with CF9, available for download here.
It relieves you of knowing much of any of the CF 9 ORM specifics, letting you quickly get your job done. Here's the nickel tour of the API:
- save( target : Object, noFlush : Boolean = false ) - Saves an instance. Sending noFlush = true will not commit the transaction (no ormFlush() call).
- delete( target : Object, noFlush : Boolean = false ) - Deletes an instance. Sending noFlush = true will not commit the transaction (no ormFlush() call).
- deleteById( entityName : String, id : *, noFlush : Boolean = false ) - Calls delete() after read()ing the instance identified
- read( entityName : String, id : * ) - E.g. read( "Contact", 2 )
- list( entityName : String, whereClause : String, params ) - E.g. read ("Contact", "firstName = ?, active = ?", [ "Joe", true ] )
It also exposes a dynamic finder (via onMissingMethod), in the form of list{EntityName}By{Prop1}And{Prop2}And...{PropN}, letting the above list() example be rewritten:
- listContactByFirstNameAndActive( "Joe", true )
Comment 1 written by Dan Vega on 7 October 2009, at 9:12 AM
Comment 2 written by TJ Downes on 7 October 2009, at 11:30 AM
Comment 3 written by TJ Downes on 7 October 2009, at 11:36 AM
Comment 4 written by Joe Rinehart on 7 October 2009, at 1:11 PM
Dan, the code for the dynamic finder is in the download (linked in the blog post). It's just a use-at-own-risk simple string parse.
Comment 5 written by Dan Vega on 7 October 2009, at 1:17 PM
Comment 6 written by Dustin Martin on 7 October 2009, at 10:48 PM
I do something very similar with Transfer and a base class for my DAO and Service object.
Very helpful indeed!
Comment 7 written by John Allen on 8 October 2009, at 12:02 AM
Comment 8 written by Seth Johnson on 19 October 2009, at 6:12 PM
Thanks!
Comment 9 written by Joe Rinehart on 20 October 2009, at 5:49 AM
Sorry about that - got lost in changing blog platforms. DL link is working again.
Comment 10 written by John Paul Ashenfelter on 16 November 2009, at 1:54 PM
<cfcomponent displayname="PersonService" output="false" extends="services.dao">
<cfset variables.entity = 'Person'>
<cffunction name="init" access="public" output="false" returntype="any">
<cfreturn this>
</cffunction>
<cffunction name="default" access="public" output="false" returntype="any">
<cfreturn this.list()>
</cffunction>
</cfcomponent>
Where Person.cfc is a basic CF9 ORM file (bunch of properties).
Or am I missing something? I'm so used to the ActiveRecord pattern everything else seems like tons of work :)
[Add Comment] [Subscribe to Comments]