DDD Without any ORM tool, is it possible !!
When reading DDD book and trying out it on a sample project that doesn’t use any ORM tool. I came across a question, is it possible to strictly implement DDD without any ORM tool !
Is there any one here who has implemented DDD on any real project that doesn’t use any ORM but pure JDBC only?
Before few days, I had a question on how to paginate and lazy load non root objects http://tech.groups.yahoo.com/group/domaindrivendesign/message/15925
Various alternatives and answers came up, but why do I need to find an alternative ! I don’t need to do any thing specific when using hibernate and just depend on the lazy loading support provided by it.
I want to paginate because I don’t want to load entire graph of few thousand objects into memory and when using hibernate and lazy loading that’s not an issue. With NO-ORM, I can achieve similar thing by hand coding dynamic proxies for lazy loading, and let repositories handle it.
However the second point is more important.
The second question is related to repositories, transitive persistence and dirty checking.
The DDD book (Chapter 6 – repositories) says “it allows freely switching persistence strategies at any time.”
Is it really possible and easy without modifying domain at all !
How about dirty checking and persistence by reachability without any ORM ?
When you save/update an aggregate root, entire graph should be saved and/or updated. How the repository will determine which objects are modified/inserted or deleted?
Probably you will need some thing like isNew() isStale() inside every entities to find out if it needs to be included as part of insert/update. And set flags when ever any setter or any other method changes state of the object. I have seen similar thing in a project which uses DDD with JDBC.
Several answers came up
Get the data from the database and determine updates, deletes, and inserts in code.
This may not be the best routine, but I use a boolean flag to determine what needs persisted. I have a property in each entity called .IsDirty. When anything inside the aggregate root needs persisted, I use the root’s repository and call root.Persist and I go through the root. The root repository then loops through each entity and tests the .IsDirty flag
Do you see any pattern in this answers ?
- It says either modify your domain model or write some thing like your little ORM to do this things.
- That says DDD is tightly bound to ORM and “Freely switching of persistence technology” means switching from one ORM to another (it could be your own).
How about Delete?
Lets say root has a collection of associated entities (In my example MessageFolder has Collection of messages)
I can do some thing like
That would remove message from the collection. When saving the MessageFolder, how the repository can find out what messages are deleted? Either message folder need to maintain a collection of removed messages or repository need to have old message folder for comparision. The first option forces me to modify MessageFolder, that mean domain model became aware of underlying persistence technology. The second option would need to load old entity which would affect performance.
It might be possible to switch to ORM from a No-ORM application but what about switching to NO-ORM from ORM ! Does that mean I will have to add custom behavior to my entities to figure out weather they are new or modified or deleted.
These are few questions that I am not able to answer my self and seeking some expert thoughts. If you have done DDD for a real life project that does not use any ORM, please comment.
Some people said CQRS and Domain events can solve this problem, however I am yet to find a working example.
There is a sample DDD application created by DDD community. The sample application uses Hibernate in persistence layer.
I wish some day DDD community would release a sample application that works on pure JDBC. As still there are lots of companies who use bare JDBC and no ORM at all.
Look at the thread http://tech.groups.yahoo.com/group/domaindrivendesign/message/16021