You are right. You can build rich models on top of Cayenne objects, either yourself and/or with the help of generation tools suggested here (although the tool would only be able to provide data access methods based on semantics). And this is great and herein lies the power of the generation gap pattern of Cayenne classes.
Why I am trying to avoid this design is cause it doesn't scale either in complexity (doesn't allow clean modularity) or in performance (which is what you were alluding to). Both are not some theoretical things, but very real use cases in real applications. So after burning myself a lot with it in the past, I am avoiding rich models at all costs. Yes, it takes time to learn how to write the services. For instance traditional DAOs indeed make little sense with Cayenne, when you have ObjectContext. So you don't have to worry about POJOs, etc. But encapsulating business logic in services does (or even logic for getting the right ObjectContext). The end result is a very elegant and easy to extend design. Also a testable design. Service oriented approach just requires a different mindset, but can give you great results. Not sure if the services discussion is OT for the present topic, but I figured it presents an opposing style of coding, so there's some use in mentioning it. Andrus On Dec 27, 2012, at 12:13 AM, emeka okafor <emeka_1...@yahoo.com> wrote: > I am a little bit surprised that you call the cayenne way "anemic domain > model". I do not see what is anemic in this case. > /rant > The fact that a domain object has the ability to call save() on itself or > not has nothing to do with anemism or richness. In cayenne you can and should > put your business logic in your domain objects. You only have problems when > you have to integrate with all the j2ee stuffs. They have services all over > the place, they create interfaces for everything (Spring really pushed the > enveloppe very far in that regard) because the implementation may change > somewhere in the future. As a result You have your DAO implemented as a > service and have to pass objects id to that service to traverse > relationships. Really unless you are having scaling problems, the DAO as a > service thing is weird. I was fortunate to work with webobjects after a > couple of years doing all the jee stuffs and only after that did I learn what > real domain driven design means, because it was natural. No need for weird > interfaces, weird pojos, weirds annotations. Now what does it have to do with > active records, actually nothing. It is just that someone said that with > cayenne you have an anemic domain model, which is not true. > /end of the rant > > > ________________________________ > From: Andrus Adamchik <and...@objectstyle.org> > To: user@cayenne.apache.org > Sent: Wednesday, December 26, 2012 6:25 PM > Subject: Re: Add ActiveRecord support to Cayenne > > In ROP case the root cause is 2 separate disjoint models (doesn't matter rich > or anemic). A single anemic model would've allowed to define a common set of > "services". > > So while I am still on this rant, I think the "rich/anemic model" discussion > at the end may come down to modularity requirements/expectations. One of the > modularity paradigms is this: "coarse-grained modules are easier to use, but > harder to reuse; and a corollary - fine-grained modules are harder to use, > but easier reuse". > > For instance WO-world wasn't very keen on modularity, so rich models worked > relatively well (or was it because the original Objective C implementation of > WO allowed for categories to redefine existing classes in runtime? ;)). JEE > and enterprise apps in general strive for better modularity so defining lots > of business logic high up in your dependency tree is going to cause lots of > pain. > > But then again, I admit not everyone is writing the same applications that I > do :) > > Andrus > > On Dec 26, 2012, at 8:04 PM, Aristedes Maniatis <a...@maniatis.org> wrote: > >> On 26/12/12 11:40am, Andrus Adamchik wrote: >>> Ilya's point that we discussed a bit offline was that AR-like design is >>> more object-oriented, with object providing all operations on themselves. >>> The context will be taken from the current thread (something we already >>> provide). One piece of theory behind it is a reference to the Fowler's >>> criticism of "anemic domain >>> model":http://en.wikipedia.org/wiki/Anemic_domain_model . >> >> I find this quite interesting. One problem we are trying to solve on our >> project right now is bringing together logic between the client and server >> entities in a ROP system. Because Cayenne entities inherit from different >> superclasses (what's with that?), it is very hard to keep the business logic >> in a one place. >> >> Anemic models are all very well, but what do you do with the code? It seems >> that all the options available to us aren't terribly convenient to use. We >> either end up with zillions of interfaces or lots of static methods. >> >> AR is the opposite of anemic. All the Rails projects I've seen tend to throw >> lots of code into the model. But because Ruby uses duck-typing instead of >> interfaces, things don't get quite so messy. Even searching is rooted in the >> model classes: >> >> Artist.find(:name, "bob").sort(:age) >> >> or something like that. >> >> Ari >> >> -- >> --------------------------> >> Aristedes Maniatis >> GPG fingerprint CBFB 84B4 738D 4E87 5E5C 5EFA EF6A 7D2E 3E49 102A