Nov 3 2008

Does ColdFusion have no real ORM frameworks?

Posted by Joe Rinehart at 9:12 AM
41 comments
- Categories: Frameworks

For the past month, I've been working like a madman with barely enough time to stop and spend with my family, much less blog meaningfully. During that time, my counterpart at Broadchoice Brian Kotek has still somehow managed to keep up fighting the good fight for common-sense OO design in ColdFusion.

Today's a little more relaxed at work, so I guess it's my turn to stir the pot a little. I'm sure this post will offend some folks who've worked long and hard on some open-source ColdFusio frameworks, but please bear with me: your work is good, saves many people much time, and is greatly appreciated. It's just been mislabelled. This post is largely about terminology, not effectiveness of technology.

ColdFusion has no ORMs (that I can find)

So, without further ado, here's what I'm postulating: there's not a single ORM framework for ColdFusion that's actually an object-relational mapping framework. Not even Transfer *really* meets the definition of ORM, even though it comes the closest.

I'm not trying to be destructive...

This post isn't a rant against the pseudo-ORM frameworks in the ColdFusion world. I've used the predominant ones and written three of my own: they're all great for increasing productivity and invaluable tools to ColdFusion developers.

...I'm illustrating differences between "real" ORM and ColdFusion "ORM".

For the past six months, I've only used Hibernate as an ORM. It represents a world a world of difference from how ColdFusion has approached object-relational mapping.

Here's the basis of our difference:

Object-Relational Mapping exists to allows you to work in purely objects and to use the framework to map the differences between object graphs and relational storage. It is *not* simply the abstraction and automation of SQL. In fact, some ORMs actually require you to write SQL: they just map what SQL to run for what operations!

The easiest example I can think of to illustrate this effectively is the idea of an an "audit" object. We'll approach it from the database side, as it's what we're most familiar with.

In just about any database design I've ever worked on, every entity has the idea of "last modified" and "last updated" columns. All too often (for my comfort), this gets reflected into properties on objects called things like getDateUpdated() or getDateCreated().

Let's pretend we've now got a new requirement to expose a getDaysSinceUpdate() getter on each object. To make it painful, let's pretend we've got 50 objects. Oi. No way we're going to go copy and paste that new <cffunction> onto every entity CFC in our system.

Good OO design says to encapsulate what changes, so we can take an obvious route: do away with these two properties and create an AuditTrail object with properties like getDateUpdated(), getDateCreated(), and getDaysSinceUpdated(). Once it's added to all of the other entities as a has-one composition, it's becomes _really_ easy to handle further cases such as tracking who performed the update.

We add them two our objects, using Transfer or Reactor or DataFaucet or whatever, and commit. Bam, a new AuditTrail table is in the database, and all of our objects now join to it via a foreign key.

The DBA, however, goes _nuts_. While we're using an optimized way of representing the new state and behavior in our object model, what we've done flies against optimally using the database. It'd be most efficient for it to just store dateUpdated and dateCreated as properties in the entities tables, not some soon-to-be-ginormous central table that's constantly going to get locked.

Sigh...that's not an ORM.

Our problem is that ColdFusion doesn't have any ORM that really maps the differences between our object graph and relations. Instead, we're using SQL abstraction toolkits calling themselves "ORMs" that treat object graphs and relational schemas as one and the same.

Conclusion


The world of "real" ORMs isn't hunky-dory either. Moving into JPA or plain Hibernate is a new world of units or work, sessions, detached vs. persistent instances, and all sorts of fun concepts. In many applications, the "simpler" approach taken by ColdFusion frameworks may actually be more effective (thought I'd wager with diminishing returns).

I have, however, had a wonderful time working with Hibernate, especially in the context of Groovy. Once the weirdness of not working in simple one-shot SQL statements wore off, I just code how I want things to work and don't worry much about the database (until it's time to create DTOs for Flex - then I'm a generated SQL control freak).

On a larger scale, I think we've seen a lot of places where the ColdFusion community has taken a looser interpretation of development terms, such as "data access object" and "object-relational mapping," than is widely accepted. In some cases, this can come back to haunt us: moving from what we think of as an ORM to something that really is an ORM can be a painful learning curve. At other times, I think it's been a pragmatic approach that opens up powerful new concepts to a larger development audiences.

Just...please...understand ORM before releasing a SQL generator with CFC hooks and putting "ORM" after its name. It's not the same.

Comments

Raul Riera

Raul Riera wrote on 11/03/08 10:18 AM

Check out cfwheels.com it has a real ORM or OOP implementations, although I am not sure you understand what ORM is if you are talking about 50 objects (models) that have 50 functions to retrieve the same data
Joe Rinehart

Joe Rinehart wrote on 11/03/08 10:45 AM

Raul,

I'd decidedly call cfwheels.com something that isn't ORM, given that it uses the database schema to implicitly create properties (relational-object mapping!) instead of using the object model as the primary store of domain modelling. It's doing nothing but reflecting database tables (as I said, effective and productive for many people, and not necessarily a bad thing!).

Further, the "ORM" in cfwheels is invasive: your object model depends on CFCs in cfwheels. A true ORM is one in which you can use an object model has no knowledge of the ORM whatsoever.

As far as having all 50 domain objects have the same getAuditTrail() method, no, I wouldn't do something as silly as write that function into each one - interfaces, subclasses, and the dynamic nature of CF and Groovy both allow much cleaner things. That's more OOP implementation than ORM, however, so talking about the "how" of its implementation would've been off topic.
Raul Riera

Raul Riera wrote on 11/03/08 10:55 AM

I am not clear by what is your concept of ORM then, since putting in simple words will be just a way to use the Data Model of an appliation without knowing which data store system the application is using.

On the wheels example, a model object doesnt need to know if its running on MySQL, MSSQL, etc. it just works when you call findAllByUpdatedAt() and it will return so without creating any logic in the model. And if you need some sql you can do it by findBySQL or by adding functions to your model object.

Sidenote, your captcha is pretty darn hard hehe
Peter Bell

Peter Bell wrote on 11/03/08 12:14 PM

Hi Joe,

Great posting, and I think Raul is helping to make your point. Too many people do think that abstracting SQL dialects or automating the creation of your SQL is an ORM. It's not. Although as you pointed out it can be useful and I'd argue that for some smaller projects it can perhaps even be a better fit than Hibernate - *especially* if your team doesn't have any Hibernate experience as it is a bit of a bear to get set up and configured.
Joe Rinehart

Joe Rinehart wrote on 11/03/08 12:33 PM

Hey Raul,

> a way to use the Data Model of an
> appliation without knowing which data store
> system the application is using

Peter put it well: what you just said is the confusion about what ORM is that I'm trying to illustrate. ORM is *not* "a way to use the Data Model". An ORM is a tool that lets you work in the domain model (objects), with it mapping the state of the domain model back to the data model. In fact, in some ORMs like Hibernate, you don't even have to create a data model - you just write objects and the ORM creates a suitable database for you.

Any good ORM will also abstract out which SQL engine you're using (MySQL vs. Postgres, etc.) transparently.
Joe Rinehart

Joe Rinehart wrote on 11/03/08 12:35 PM

> Great posting, and I think Raul is helping to make your point.

Thanks Peter!

> Too many people do think that abstracting SQL dialects or
> automating the creation of your SQL is an ORM.

Very well put!
Raul Riera

Raul Riera wrote on 11/03/08 12:47 PM

Iif you look for the concepts of ORM you will see that pretty much sums up what I just said and you qouted as "proof" of your theory.

"Object-relational mapping (OR mapping) products integrate object programming language capabilities with relational databases managed by Oracle, DB2, Sybase, and other RDBMSs. Database objects appear as programming language objects in one or more existing object programming languages. Often, the interface for object-relational mapping products is the same as the interface for object databases."

"an ORM tool is simply any tool that joins relational data in the context of a business object required for some real world application."

"An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data."

Now, I dont know if you want to define Hibernate here or ORM in general.

BTW on Wheels you dont have to specify the type of data model its handle by the ORM
Joe Rinehart

Joe Rinehart wrote on 11/03/08 1:25 PM

Raul,

You're still confusing ORM with simply reflecting data schemas into objects. They're different (and opposite), and your quotes are either used incorrectly (the last) or you've misunderstood them. I'll cover each.

The first, "Object-relational mapping (OR Mapping)" is from www.service-architecture.com. It's a good article, and worth reading fully. It supports my view of ORM, stating that "[orm] products should be be used when you want to take advantage of transparent persistence and use a relational database." In other words, use ORMs when you want to write objects and save them in a database, not simply use your database as data-centric objects. The entire article actually covers many persistence strategies, including object databases: definitely an object-first view of ORM!

The second, "an ORM tool is simply any tool that joins relational data in the context of a business object," is from the Wikipedia article on ORM. It's dead on when it states that it "joins relational data *in the context of a business object*". The business object is the holder of context and structure, not the database! Again, ORM is hardly treated as a simple way to access a data model.

Lastly, "An object that wraps a row in a database table or view..." isn't about ORM at all. It's Fowler's definition of the Active Record pattern, a notoriously data-centric implementation of ORM. Again, though, it starts with the object:

"An object carries both data and behavior. Much of this data is persistent and needs to be stored in a database. Active Record uses the most obvious approach, putting data access logic in the domain object."

In response to your last comment, I'm defining ORM in general. ORM lets you work in objects, not tables or rows. ORM lets you resolve differences between the non-scalar world of object graphs and the world of row-based database tables. ORM lets you persist concepts such as inheritance hierarchies that don't even have meaning in a relational database.

Wheels ORM? Not object-relational mapping. Sure, it's a quick an intuitive way to manipulate data in a database - I won't argue that. But it's not ORM. Its idea that "ORM stands for 'Object-Relational Mapping' and means that tables in your relational database map to classes in your application" is the exact _opposite_ of what ORM means.
Raul Riera

Raul Riera wrote on 11/03/08 1:33 PM

Just to clarify things, ActiveRecord is ORM or not? if not, then you should re title your post to there is no real orm on ColdFusion, Ruby, PHP or Python.
Raul Riera

Raul Riera wrote on 11/03/08 1:50 PM

And yes, once agaian with Wheels, everything you said is how Wheels manage ORM, you have a cfc (since those are the objects of ColdFusion) with all the data mapped in it, just like Rails does it (reason for my previous question about ActiveRecord) and since you mentioned ActiveRecord as an "implementation of ORM" I still miss your point on no ORM in ColdFusion
Henry Ho

Henry Ho wrote on 11/03/08 1:52 PM

no real ORM for CF8, just wait for CF9 or...

CF Groovy w/ Hibernate
http://www.barneyb.com/barneyblog/2008/07/07/cf-groovy-hibernate-sample-app-ideas/
Joe Rinehart

Joe Rinehart wrote on 11/03/08 2:25 PM

Raul:

I'll make it concrete: If you can find an ORM for ColdFusion that lets me create, save, relate, and list a plain-jane CFC that doesn't extend _anything_ from a framework I'll say that we've got the start of an ORM for ColdFusion. As I said, Wheels fails that test: you've got to extend its "Model", and it uses the database to figure out the CFC's properties.

As far as Ruby, PHP, and Python, I've no idea about what ORMs are available - it'd be silly for me to claim anything about them.
Joe Rinehart

Joe Rinehart wrote on 11/03/08 2:27 PM

Henry,

Yeah, CF9 is looking promising, and Barney is a madman.

At Broadchoice, our Workspace is powered by Groovy on Spring, persisted with Hibernate. The "iPhone" client is actually HTML backed by CFML, so it's the first production CF + Model-Glue + ColdSpring + Spring + Hibernate + Groovy app I know of.
Henry Ho

Henry Ho wrote on 11/03/08 2:30 PM

Joe,

oops, who's Barney?

If you're already using Spring, Hibernate & Groovy, why use CFML still? Is jsp that bad??
Brian Kotek

Brian Kotek wrote on 11/03/08 2:53 PM

Henry: yes, JSP is that bad.
ike

ike wrote on 11/03/08 3:05 PM

Ummm... this article seems much less clear than Brian's follow up.

http://www.briankotek.com/blog/index.cfm/2008/11/3/Joe-Rinehart-Stirs-the-ObjectRelational-Mapping-ORM-Frameworks-Pot

Based on Brian's follow-up I gathered he was saying that the reason why CF ORMs arent "true" ORMs is because they generate CF from the database instead of working the other way around and generating SQL from the objects. Given that (fairly clear) definition, it seemed somewhat obvious that both FarCry and the most recent version of DataFaucet actually do fit that criteria. So of course I posted this: http://datafaucet.riaforge.org/blog/index.cfm/2008/10/14/BestOfBothWorlds

But after now reading this article I'm left wondering what your criteria are for calling something an ORM?

My interpretation of much of what happens in the CF community is actually the opposite of what you've said about us having "looser definitions" actually... It seems to me like our definition of a DAO or a "gateway" is much more specific than what GOF suggested. RE: Matt Woodward on design patterns http://www.mattwoodward.com/blog/index.cfm?event=showEntry&entryId=08492A7A-E4A1-1E42-FF9FB2C22097A947
Chris Peters

Chris Peters wrote on 11/03/08 3:11 PM

Wheels may not be the text-book definition of ORM, but I think it is a very practical implementation given the "reality" of interacting with databases with ColdFusion. You even list the central caveat above with your AuditTrail object, which is true for all SQL-based databases.

And ColdFusion is so bad at dealing with objects that I think Wheels "uses what it has." The only way that I've been able to deal with so many objects in a manner that performs decently is to write the objects in Java and invoke them with CF. Maybe the uber-ORM for CF will take that stance? Or hopefully all of these vague NDA'ed references to CF9 will solve some of that...

My 2 cents, for what it's worth. :)
Brian Kotek

Brian Kotek wrote on 11/03/08 3:21 PM

Ike, the database-centered domain model forced upon developers by existing frameworks is really just one issue (though arguably the most important issue). The other is transparency: all of the existing solutions that I've seen for CF require that the domain model be coupled very tightly to the framework being used. This is the issue that Joe is pointing out above. If you're forced to extend some framework-specific object in order to use the ORM, it's not a very ideal solution. It might be a very useful way to speed up development (I use Transfer for all of my CF-related models), but it comes with a very tight coupling between your object model and the framework in use.
ike

ike wrote on 11/03/08 3:30 PM

Okay, this is the statement that made it clear for me:

===
Further, the "ORM" in cfwheels is invasive: your object model depends on CFCs in cfwheels. A true ORM is one in which you can use an object model has no knowledge of the ORM whatsoever.
===

Everything else just confused me more about the distinction you were trying to make. And given this as the distinction, then yes, you're right, FarCry and DataFaucet don't currently do that either...

Not sure about FarCry, but I could do that with DataFaucet relatively easily. Right now it will add columns to existing tables, but I still have in the feature list the ability to automatically populate that column with a default value or the ability to modify the data type of existing columns... I think the recent CFMeetup recording shows me using that to automate schema updates from the object the way you describe Hibernate doing... Having done that, I could then simply build an armature that would allow you to separate the object introspection from the object and allow you to define persistence strategies separately. I'm not entirely opposed to doing that although I don't personally have any business cases that represent a need for it.

And we need a name for any concept if we're going to talk about it and be able to make these conversations productive. If you want to recommend that people start making the distinction between ORMs and ROMs that's fine, although personally I don't think that distinction adds much value. I'm happy to continue generalizing them all as "ORM" and (re: Matt's comments about GOF) and discussing the differences in approach under that blanket.
Ross

Ross wrote on 11/03/08 3:31 PM

Hey Joe,

A slight change in direction but something which I've been thinking about recently is some of the new ideas in CF such as frameworks & ORM's seem to be a transplanted from the Java world (ColdSpring & Spring and also Transfer & Hibernate). Yet in my opinion CFML is far from equivalent to Java on many levels. So like Henry is saying why not just use jsp and reduce the overhead?
Ross

Ross wrote on 11/03/08 3:37 PM

Hey Joe,

A slight change in direction but something which I've been thinking about recently is some of the new ideas in CF such as frameworks & ORM's seem to be a transplanted from the Java world (ColdSpring & Spring and also Transfer & Hibernate). Yet in my opinion CFML is far from equivalent to Java on many levels. So like Henry is saying why not just use jsp and reduce the overhead?
ike

ike wrote on 11/03/08 3:38 PM

@Brian - thanks Brian -- that's what I gathered when I read through the comments -- but I'd posted my first reply before I finished reading the comment thread. :)

I actually don't care for that as a definition of "ORM" because as a definition, it depends on an idea that's not expressed in the acronym. None of the individual words (Object, relational, mapping) actually express anything at all about when or where or how the mapping is accomplished, or whether or not the business model is aware of the mapping.

I'd much rather describe that the way that Fowler describes Domain Specific Languages (DSL) as being an "internal DSL" or an "external DSL". Where we might describe an ORM as being an "internal ORM" like Transfer, Wheels, FarCry and the current iteration of DF, or an "external ORM" like Joe's suggesting as being a "true" ORM.
Joe Rinehart

Joe Rinehart wrote on 11/03/08 3:39 PM

@Henry Ho,

Barney = Barney Boisvert = The guy who writes the blog you linked to about Groovy, Hibernate, and ColdFusion :)

JSP = pain, esp. now that Railo is available for the presentation layer.
Joe Rinehart

Joe Rinehart wrote on 11/03/08 3:46 PM

@Ike,

> I could do that with DataFaucet relatively easily.

Then I think we'd have a contender ;) There are more criteria for what's ORM vs. what's SQL abstraction, I'll write a longer comment in a moment.
Joe Rinehart

Joe Rinehart wrote on 11/03/08 3:49 PM

@Chris Peters

>Wheels may not be the text-book definition of ORM,
>but I think it is a very practical implementation
>given the "reality" of interacting with databases with
>ColdFusion.

I wholeheartedly agree that it's a practical and productive way to get things done, and thanks for working with the cfwheels team to provide it to the community.

What I don't agree with is that it should be labelled ORM - it's not mapping objects to databases. It's relying on the developer having a knowledge of the database, and providing a really easy way to manipulate the db's contents. Again, practical, productive, powerful, and easy to understand. It's just not ORM work (which can be powerful but absolutely dizzying to understand!).
Hal Helms

Hal Helms wrote on 11/03/08 4:17 PM

Thank you, Joe! As Brian can attest to, I've been ranting about so-called "ORM"s in CF for quite a while. The idea that the database determines the object model is, for me, a non-starter. I'd rather write my own SQL than take this Devil's compromise.

Too often, decisions completely incongruent with OO are justified on the basis of having to compromise "OO purity" as though OO congruence were an unattainable -- perhaps undesirable -- utopian goal.

Having just spent the last two weeks doing OO classes, I've seen a lot of nonsense employed with this justification. The worst of it is that all this work is done, creating classes, writing controllers and service layers and, finally, very little benefit is being gained.

I have a lot of respect for Isaac, so if he says DataFaucet begins with the object model, I'm delighted. (Do I have that right, Ike?)
Joe Rinehart

Joe Rinehart wrote on 11/03/08 4:18 PM

@Ike,

I started to comment again, but it got really long. Keeping knowledge of the ORM outside of the domain model isn't my primary concern: it's solving all of the problems an ORM needs to solve that I'm more concerned with for finding a "true" ORM. I just think any ORM that's well designed should let me use any object model with it, not just one that extends special base classes.

Instead, I wrote another blog entry, describing the problem areas between object models and relational schemas commonly solved by ORMs:

http://www.firemoss.com/post.cfm/what-makes-a-framework-an-orm

In particular, I haven't seen any support for granularity, identity resolution, or polymorphic queries. I'm not sure if any ColdFusion ORMs effectively support inheritance, either.
ike

ike wrote on 11/03/08 5:29 PM

@Hal - DataFaucet is a bit of an odd duck I guess in that it doesn't really follow the conventions of either what we typically see in CF or of what you might typically see in Java.

That probably has a lot to do with the fact that when I started working on it was back when CF5 was what was available and so many of the concepts were really purely my own because far from having a body of db-abstraction work in CF at the time, we didn't even have objects!

What I set out to do at the time was to abstract SQL at a much lower level than you see in the other ORMs like Transfer or Reactor. Transfer and Reactor focus on specific ORM-like interactions with the database and then have some object abstractions for custom queries (i.e. TQL), that are somewhat limited and so any querying of any complexity is likely still done with cfquery tags. By comparison DataFaucet begins with a custom-query building abstraction and has subsequently layered the ORM-like interactions on top of the query-building language. And this also allows me to do some very complicated things like and/or keyword searching with a simple one-line OO abstraction.

To get back to your question of whether DF starts with the DB or starts with the Objects, it actually does either depending on what you need or want. It had an active record implementation for a while and I added the ability to make them self-installing in a recent version, so the object will create its own db tables on demand. And then a little later on still I added a cfproperty abstraction. However although the object will create the db table for you, the name of the table is declared within the object. Now Joe's said that's not his primary concern, which is fine. DF handles some of the things he described although I'd hesitate to say it handles all of them.

But because the system itself is designed fundamentally as a very low-level abstraction of the querying language, it's always been fairly easy to repurpose the query-building language to suit new use cases. And so from my perspective, the external ORM that can be applied to any existing object model is just a different use case it could be extended across.

Although I must admit that I do tend to have mixed feelings about that whole subject of "OO purity". Historically it seems like I can recall having received criticism for my object models *not* being "anemic domain models" and then later reading articles where you or Ben Nadel (etc.) pointed out that my object model that had been criticized was actually more in keeping with the fundamental OO philosophy. That could just be a strange perception on my part because of an unusual chain of events, I don't know. The truth is I'm entirely self-taught, so everything I know about OO philosophy is from what I've read.

@Joe - read the other article... pretty sure I can do some of those things with DataFaucet's active record implementation - granularity, and polymorphic queries spring to mind in particular. But having read the other article, I know that right now it doesn't include any tools for reversing the polymorphism question - i.e. fetch records x,y,z and populate MaleUser vs. FemaleUser objects.

It does however support some of the polymorphism questions going the other direction - you can have MaleUser and FemaleUser. It's the only CF db tool I know of right now that supports multi-table inheritance mapping. I actually didn't realize that there was much demand for that until I read this thread from the Transfer list. http://groups.google.com/group/transfer-dev/browse_thread/thread/75f86980c8831ac7?fwc=1&pli=1

But yeah, there are things in your list it doesn't currently support.
Tony Garcia

Tony Garcia wrote on 11/03/08 6:49 PM

While some people wax philosophically on "OO purity" and what constitutes a "true ORM" I'll be busy using the tools that make me productive.
While I don't currently use any of CF's "db abstraction tools", if (when) I ever do, I'll take your word for it and not call it an ORM.
Mark Mandel

Mark Mandel wrote on 11/03/08 8:42 PM

Wow!

Big blog post, and having read through it all, (and also reading your ORM post), in a lot of ways, I think you are right.

When I first started Transfer, I didn't know much about ORM (only with a slight knowledge of EJB back at University), and this has been a learning experience since day 1.

That being said, its interesting to note, that the development plan for Transfer for the next few versions (albeit mostly in my head), were specifically tailored towards solving some of the problems you have expressed here. Most notably things like Inheritence mappings, DDL creation, (although how I will solve the Granularity issue.. is an interesting one), to allow you to focus more on the Object model at hand, rather than the underlying database.

As per the coupling of the model to the framework - yep, that kinda sucks. But the trade off you get with Transfer, is the generated code base. In retrospect, this could probably have been done in a more decoupled way (mixins, mapping options, etc), but because its there, I'm able to leverage it to provide the object generation side of things... so six to one, half a dozen to the other.

Who knows, maybe one day, I'll just decide to rewrite it all from the ground up ;o)
Mark Mandel

Mark Mandel wrote on 11/04/08 2:40 AM

@Hal -

I want to clarify something with you, because its something you seem to consistently say, that doesn't seem to make sense to me.

In my mind (correct me if I'm wrong), you seem to beings saying that if the ORM doesn't actively create the database schema for you - then it isn't really an ORM.

That somehow, if the schema isn't generated by the ORM, then it's database driven? Rather than OO design driven?

If that is the case, I would have to disagree - while having an ORM create / manage the database for you is very * helpful * in developing an OO solution, it doesn't mean that it can't be done.

There is no reason you couldn't design your OO model first, and then implement a database persistence based on that.

It seems to me to be an issue more of the order of software design - whether the db, or the OO model is designed first, and no matter what you do, that can't actually be controlled.

(That being said, your interview on CFConversations was what made me put DDL support for Transfer on the roadmap, so thanks for that)
Hal Helms

Hal Helms wrote on 11/04/08 4:32 PM

@Ike: I'm going to take a look at DataFaucet, Ike. Thanks for the rundown.

@Mark: Mark, I'm not arguing that Transfer/Reactor aren't ORMs. Rather, I'm saying that any process that starts with the database is fundamentally wrong. My problem is with the people I've spoken with who use those -- let's call them ORMs -- since they all seem to start with the database.

I've seen the result of this working with students and developers: a ton of machinery supposed to make life easier but just making their code more obscure. Anemic domain models that combine the worst aspects of OO with the worst of procedural. And THIS is what's being largely encouraged in the CF world.

But I am definitely a voice crying in the wilderness. But for me, I'm eschewing those "solutions". It just seems to me that the cure is far worse than the disease.
Mark Mandel

Mark Mandel wrote on 11/04/08 4:44 PM

@Hal,

I agree with you that starting from the DB is the wrong approach.

That being said, can you please explain how Transfer forces you to start from the DB level?

Personally, I don't use Transfer that way, and never have, so I struggling to understand it.
Hal Helms

Hal Helms wrote on 11/05/08 8:36 AM

@Ike: I'm going to take a look at DataFaucet, Ike. Thanks for the rundown.

@Mark: Mark, I'm not arguing that Transfer/Reactor aren't ORMs. Rather, I'm saying that any process that starts with the database is fundamentally wrong. My problem is with the people I've spoken with who use those -- let's call them ORMs -- since they all seem to start with the database.

I've seen the result of this working with students and developers: a ton of machinery supposed to make life easier but just making their code more obscure. Anemic domain models that combine the worst aspects of OO with the worst of procedural. And THIS is what's being largely encouraged in the CF world.

But I am definitely a voice crying in the wilderness. But for me, I'm eschewing those "solutions". It just seems to me that the cure is far worse than the disease.
ike

ike wrote on 11/10/08 2:22 AM

It looks like I must have accidentally unsubscribed because I don't think I got an email from Hal's reply...

Anyway, I wanted to drop another brief note about this follow-up with some information about progress on a PersistenceService in the DataFaucet core that represents an external ORM where the objects are unaware of the persistence engine.

http://datafaucet.riaforge.org/blog/index.cfm/2008/11/10/New-PersistenceService-option-in-DataFaucet-ORM

It's still nacent... very little testing and there are still things in it that I know don't work yet, but... it's only 2 days work. :)

p.s. Thanks Hal. :)
Jared Rypka-Hauer

Jared Rypka-Hauer wrote on 11/11/08 10:23 AM

Hal,

Just an observation, you seem to be assuming a direct link between Transfer and anemic domain models (emphasis on "seem" because I could be misreading you). In point of fact, this couldn't be further from the truth.

It just ain't true.

I'm not arguing that Transfer really is an ORM, I'm arguing that your association with Transfer and the anemic domain antipattern is misinformed. Transfer's Decorator object allows you to apply any behavior you need to the Decorator for any object. Your TransferObjects implement the behaviors your application needs and if done right become the domain model for the application. In fact, when Mark was building Transfer he and I spent many hours in conversation about domain modeling and real-world entities/behaviors... so it's built to support that from the ground up.

One other quick point: Transfer may require you to start with it's Decorator, it may not allow you to plug POCFO as a decor, but it certainly doesn't require you to start with the database, either. Being closely coupled to the framework doesn't have to imply that it's data-centric and that doesn't directly imply that anything written with it will be anemic. Concepts like "tell, don't ask" and DRY can be applied just as well to a TO or a Decorator as to a POJO or a POCFO.

Anyway, I wanted to dump those factual points off here and will end with this:

Joe, excellent and provocative post and something I hadn't enough knowledge of to comment on. One of your great strengths is the breadth of your experience and you've provided us a great deal of information over the years as a result. Keep it comin', dude.
Jared Rypka-Hauer

Jared Rypka-Hauer wrote on 11/11/08 10:24 AM

PS - Hal challenged me to blog about using Transfer to build a domain first and implement behaviors instead of anemic services. I shall try to rise to that challenge myself over the next few days. :D
Thinkpad T60 battery

Thinkpad T60 battery wrote on 11/19/08 4:12 AM

The world of "real" ORMs isn't hunky-dory either. Moving into JPA or plain Hibernate is a new world of units or work, sessions, detached vs.
Ah I think that is the most problem.
Chris Peters

Chris Peters wrote on 11/19/08 7:47 AM

Holy crap, did someone's laptop battery just leave a comment on a blog?
Nathanael Waite

Nathanael Waite wrote on 12/19/08 8:41 AM

You know I am a little late to this blog. But it is interesting to look at how we as developers are striving to speed up development by using ORMs when maybe it we should look at our database vendors to solve some of these issues. For example using CACHE a completely object database [ODMS] would resolve alot of our issues.

Don't get me wrong I am still heavily entrenched in TSQL. But maybe we should really change our focus from relational db to object db. Seems like a switch from flat file to relational a couple of years ago.

http://en.wikipedia.org/wiki/ODBMS
http://www.intersystems.com/cache/index.html
http://www.service-architecture.com/products/object-oriented_databases.html
cheap wow gold

cheap wow gold wrote on 12/21/08 1:10 AM

Nice job! Thanks for your information.

Write your comment



(it will not be displayed)