aspose file tools*
The moose likes Architect Certification (SCEA/OCMJEA) and the fly likes JEE5 still pushes for anemic domain model ? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » Architect Certification (SCEA/OCMJEA)
Bookmark "JEE5 still pushes for anemic domain model ?" Watch "JEE5 still pushes for anemic domain model ?" New topic
Author

JEE5 still pushes for anemic domain model ?

Ronald Wouters
Ranch Hand

Joined: Apr 28, 2005
Posts: 190
Hi all,

I started on my assignment for part II with the intention not to end up with an anemic domain model. I had the firm intent that when I used EJB3 Entities they would have rich behavior. However, ...
I have done the design sequence diagrams for two of the five use cases now and updated the design class diagram accordingly and guess what ? Until now there are mostly getters/setters in my "domain" classes. I have noticed that as soon as you start using patterns like a Model Facade or say you want to use an EJB3 Timer Service, or even if you want to use the Value List Handler (with session facade strategy), the use of these patterns all seem to lead towards a rather anemic domain model (my EJB3 Entities that is).
All these patterns exist for good reason and they solve very real problems indeed, but the consequence almost inevitably (at least to me) seems to be a rather poor, in behavior that is, domain model.
Is it just me or have you also noticed this to some degree ? If it's just me and you guys have a rich behavioral domain model, please let me know because that would mean I have some serious redesigning to do.

Regards.



Sun Certified Developer for the Java 2 Platform
Sun Certified Enterprise Architect for the Java Platform, Enterprise Edition 5
Hong Anderson
Ranch Hand

Joined: Jul 05, 2005
Posts: 1936
Hm, I don't have experience in implementing systems using EJB 3.

But for me, domain model will be good or bad, it's not depend on frameworks/technologies we use. It's depend on how we analyze and design.

Could you please be more specific? Are you saying that Java EE 5 prevents us to design good domain model?

SCJA 1.0, SCJP 1.4, SCWCD 1.4, SCBCD 1.3, SCJP 5.0, SCEA 5, SCBCD 5; OCUP - Fundamental, Intermediate and Advanced; IBM Certified Solution Designer - OOAD, vUML 2; SpringSource Certified Spring Professional
Ronald Wouters
Ranch Hand

Joined: Apr 28, 2005
Posts: 190
One example I can give is this :
In my assignment I have an Auction domain model class. I am designing/implementing my model classes as ejb3 Entities. A typical method I wanted to add to this class was "start" meaning you start the auction. This seemed like a logical place to put this method right ? This method would need to be called from a collaborating domain model class (another ejb3 entity). So, you would have an EJB3 Entity class Auction with a start method. But then you start thinking about all sorts of implementation details like, how will you end the auction once you have started it ? Does it have to be transactional ? What about security ? You start thinking about things like maybe I should use an EJB timer for this ? You "try it out" in a sequence diagram to get a "feel" for the dynamics of the scenario taking into account all the NFRs I just mentioned above and ra ra ra, what happened ? The start method can no longer be on the entity because entities do not support timeout methods. You can imagine other scenarios like this. You start by putting the business method where it belongs, on the entity / model class, then JEE technology implementation requirements force you to do otherwise.
Well maybe it's not the technology as such but the NFRs of the assignment in combination with the technology being used to implement those NFRs, I am not sure anymore now ...

Regards
J J Wright
Ranch Hand

Joined: Jul 02, 2008
Posts: 254
Does it have to be transactional ? What about security ?


Because EJB3 entities are POJOs they obviously don't have access to any container services. That doesn't me you can't implement business logic/algorithms specific to the entity in the entity. If it cuts across multiple entities then put it in an application service. The point is you're not going to be calling that business logic directly; you're going to be invoking it via a session bean that does support transactions, security and can also be a timed service.


SCJP, SCWCD, SCBCD, SCEA 5
Ronald Wouters
Ranch Hand

Joined: Apr 28, 2005
Posts: 190
Jonathan Aotearoa wrote:The point is you're not going to be calling that business logic directly; you're going to be invoking it via a session bean ...


My point exactly !!!
Best case you will end up with kind of a "double layer" of "business" logic : one call, a "wrapper" business method (on the session bean/application service) to make use of the appropriate JEE container services, and the second call which may simply be a delegate call to the Entity/model class. However, you would first have to retrieve the entity again before you could even make the second delegate call, otherwise the entity would not be "managed" by the entity manager and you would not be able to persist any changes. You would obviously want to give similar names to the methods on the session bean and entity or even give the Session bean and entity the same class name (but in a different package so they would have distinct FQN). If you do the latter, you even end up with a double "model" layer if you can call it that ...



J J Wright
Ranch Hand

Joined: Jul 02, 2008
Posts: 254
I know what you mean, and I'm not sure I have an answer. For example, EJB3 entities are often trumpeted as a replacement for DTOs, but DTOs don't implement business logic (admittedly you could adress this using the Interface Segreation principle). That said, I don't think anyone would go back to the EJB 2 days!
Hong Anderson
Ranch Hand

Joined: Jul 05, 2005
Posts: 1936
However, you would first have to retrieve the entity again before you could even make the second delegate call, otherwise the entity would not be "managed" by the entity manager and you would not be able to persist any changes.
I don't sure what you mean, why do we have to retrieve the entity again?

I think about an example, if we implement an Java EE 5 RPG game, we have session bean, AutoFightBean, and call method fight().

In method fight, we query current characters and current opponents.
After that we call method autoFight for each character, this method will use best strategy for each character against opponents. If win the battle, update EXP point for each character and persist to repository.

Isn't this good enough? Or I don't understand your point?
Ronald Wouters
Ranch Hand

Joined: Apr 28, 2005
Posts: 190
Indeed, it is possible to pass an updated detached entity from the webtier as a parameter to a method of a stateless session bean and simply call the entity manager's merge method passing the entity as a parameter. Doing this will attach the entity back to the current persistence context and eventually cause the new state of the entity to be synchronized with the database when the next flush is done.
You should however consider the possibility that during the time the entity was detached it was removed by another user in which case the merge operation will fail with an IllegalArgumentException. The detached entity may also have been updated in the mean time in which case the merge will overwrite any changes done by another user.
In case you are using a statefull session bean with an extended-scope persistence context and your entity is a member variable of the statefull session bean, so part of the stateful session bean's state, then it was never detached in the first place. In that case however I would assume the entity never "crossed-over" to the webtier, thereby never leaving the current persistence context scope, and the values used to update the entity's state are being passed in as parameters to the method call on the statefull session bean instead of the entity itself.

Regards

J J Wright
Ranch Hand

Joined: Jul 02, 2008
Posts: 254
I'm not trying to nitpick, and I know this is going off the original topic a little, but

The detached entity may also have been updated in the mean time in which case the merge will overwrite any changes done by another user.


Not if you're entities have a version property, which should always be the case if you're detaching and merging them.
Ronald Wouters
Ranch Hand

Joined: Apr 28, 2005
Posts: 190
You are absolutely correct about the version property.

To get back to the original topic, the ejb3 in action book, chapter seven says this:
A rich domain model on the other hand, encapsulates both object attributes and behavior and utilizes objected oriented design such as inheritance, polymorphism and encapsulation.
. However, the "business behavior" shown in this book is "limited" to getters and setters.
In his article on anemic domain models , Martin Fowler says
The catch comes when you look at the behavior, and you realize that there is hardly any behavior on these objects, making them little more than bags of getters and setters.
.
An OO guru like Fowler, doesn't consider getters/setters "real" business behaviour and I agree with him on that.
That is also what I was trying to get across in my original posting. Taking advantage of JEE container services, by using core JEE design patterns, reduces the ejb3 entities to little more than bags of getters and setters.

Regards.
J J Wright
Ranch Hand

Joined: Jul 02, 2008
Posts: 254
This is a really interesting topic. After looking at several blogs/articles on the subject it seems there's a lot of discussion and disagreement, but very few solutions to the problem, although Spring tries to tackle it with AOP.

Some interesting links on the subject:

http://bverma.blogspot.com/2008/04/why-i-like-anemic-domain-model.html
http://www.infoq.com/articles/ddd-in-practice
Hong Anderson
Ranch Hand

Joined: Jul 05, 2005
Posts: 1936
I can't follow you, Jonathan. How come AOP relate to this topic? Could you please to explain more?

And links you posted don't relate to this topic, I think this topic is about Java EE 5 prevents us to design good domain model

However, I don't quite understand yet how does it prevent good design, you discussed about JPA, do you mean JPA design doesn't support Entity classes to have business methods, or you mean something else?

Maybe, I don't understand because I lack experience in EJB 3. Can anyone please to say clearly, how Java EE 5/EJB 3 prevents us to add business methods to Entity classes, what will happen if we do?
J J Wright
Ranch Hand

Joined: Jul 02, 2008
Posts: 254
The problem with having JPA POJOs for you domain model in an EE environment is that you can't inject an entity manager into them. That means your domain model objects can't even do the basics like persist themselves. People get round that by introducing a service layer made up of stateless session beans. The result is an anemic domain model with lots of transaction scripts.

I looks like Spring addresses this issue with the help of aspect oriented programming and dependency injection by injecting resources into a POJO after it's been instantiated by a persistence provider. The example discussed here talks about Hibernate, but the principle is the same.

The InfoQ article talks about using Domain Driven Design to combat anemic domain models. Some of the comments are also very interesting in relation to what we're discussing here - i.e. people arguing about whether an anemic domain model really is that bad.

The point is that there's a lot of people out there asking the same question, so it would seem reasonable to assume that the EJB3 architecture is directly responsible for the proliferation of anemic domain models.
Ronald Wouters
Ranch Hand

Joined: Apr 28, 2005
Posts: 190
Jonathan Aotearoa wrote:The problem with having JPA POJOs for you domain model in an EE environment is that you can't inject an entity manager into them


One last thought before signing of for the day (feeling sleepy here). What if you inject an entity manager in a session bean and call a setter for the entity manager on the entity. Inside the entity, the instance variable holding the reference to the entity manager would marked @Transient. The entity could then maybe say something like: this.myEntityManager.persist(this). Could this work ?
Talk to you guys tomorrow.

Hong Anderson
Ranch Hand

Joined: Jul 05, 2005
Posts: 1936
Many thanks, Jonathan, I understand what you mean now.

Jonathan Aotearoa wrote:The problem with having JPA POJOs for you domain model in an EE environment is that you can't inject an entity manager into them. That means your domain model objects can't even do the basics like persist themselves. People get round that by introducing a service layer made up of stateless session beans. The result is an anemic domain model with lots of transaction scripts.

We cannot blame Java EE 5, because usually we cannot DI to post-instantiation beans. Normally we cannot do that in ANY environment, not just Java EE 5. Aspectj can help, but it's a different story.
And about domain objects persist themselves, it is just Active Record pattern, for me it's not object-oriented but it's data oriented.

If you have read Domain-Driven Design (I believe you have), Eric suggests to use Repository. You can read DAOVersusRepository.

But I think your main point is, we cannot inject dependencies to Entity domain objects, right? Can we use Service Locator pattern?

So far, I understand, I don't think Java EE 5 is responsible for this problem. If I misunderstand anything, please tell me.

And to clarify, not all domain models are in Entities, we can also have domain models in Services, Value Objects, and Modules (refer to DDD).
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: JEE5 still pushes for anemic domain model ?