Edit: This is not a conflict on the theoretical level but a conflict on an implementation level.
Another Edit: The problem is not having domain models as data-only/DTOs versus richer, more complex object map where Order has OrderItems and some calculateTotal logic. The specific problem is when, for example, that Order needs to grab the latest wholesale prices of the OrderItem from some web service in China (for example). So you have some Spring Service running that allows calls to this PriceQuery service in China. Order has calculateTotal which iterates over every OrderItem, gets the latest price, and adds it to the total.
So how would you ensure that every Order has a reference to this PriceQuery service? How would you restore it upon de-serializations, loading from DBs, and fresh instantiations? This is my exact question.
The easy way would be to pass a reference to the calculateTotal method, but what if your Object uses this service internally throughout its lifetime? What if it's used in 10 methods? It gets messy to pass references around every time.
Another way would be to move calculateTotal out of the Order and into the OrderService, but that breaks OO design and we move towards the old "Transaction Script" way of things.
Original post:
Short version: Rich domain objects require references to many components, but these objects get persisted or serialized, so any references they hold to outside components (Spring beans in this case: services, repositories, anything) are transient and get wiped out. They need to be re-injected when the object is de-serialized or loaded from the DB, but this is extremely ugly and I can't see an elegant way to do it.
Longer version: For a while now I've practiced loose coupling and DI with the help of Spring. It's helped me a lot in keeping things manageable and testable. A while ago, however, I read Domain-Driven Design and some Martin Fowler. As a result, I've been trying to convert my domain models from simple DTOs (usually simple representations of a table row, just data no logic) into a more rich domain model.
As my domain grows and takes on new responsibilities, my domain objects are starting to require some of the beans (services, repositories, components) that I have in my Spring context. This has quickly become a nightmare and one of the most difficult parts of converting to a rich domain design.
Basically there are points where I am manually injecting a reference to the application context into my domain:
- when object is loaded from Repository or other responsible Entity since the component references are transient and obviously don't get persisted
- when object is created from Factory since a newly created object lacks the component references
- when object is de-serialized in a Quartz job or some other place since the transient component references get wiped
First, it's ugly because I'm passing the object an application context reference and expecting it to pull out by name references to the components it needs. This isn't injection, it's direct pulling.
Second, it's ugly code because in all of those mentioned places I need logic for injecting an appContext
Third, it's error prone because I have to remember to inject in all those places for all those objects, which is harder than it sounds.
There has got to be a better way and I'm hoping you can shed some light on it.