Why don't you just detach the entity/data objects with deep or shallow
clone or similar? Minimal duplication...

**
Martin

2012/2/12 Bas Gooren <[email protected]>:
> Hi All,
>
> I have an architectural question about wicket, DDD and the service layer.
>
> Let's say we have a simple JPA entity (Customer), and a few simple CRUDL
> screens.
> For database access, we have a DAO layer (CustomerDao) which delegates to an
> EntityManager, and provides some convenience methods for searching.
> We also like to have clear boundaries, so we have a thin service layer which
> wraps persist() and delete() calls in a transaction before forwarding them
> to the DAO layer (@Transactional, as provided by guice-persist).
>
> A wicket model fetches one or more customers (by id or by running a search),
> and attaches to a form. In the form we use PropertyModels which push their
> changes to the entity, and in onSubmit() we call service.persist(entity).
> This means that the actual changes to the model happen outside of the
> transaction (in wicket code), and within the transaction (/service layer) we
> merely call persist() and flush().
>
> Then parts of the app need something a bit more advanced, so we decide to
> apply parts of DDD and put logic where it belongs (on the domain models).
> However, some logic coordinates multiple models, so we add a domain- or
> application-service for that.
> The good thing about DDD is that it's a lot more clear what happens
> (intent). We now realize that having a persist() method on a entity-based
> service now looks like a bit of a code smell, since it does not capture
> intent at all. Also, since the changes to the model happen in wicket, before
> the service layer is called, I feel that the service layer is not doing
> anything to act as a boundary. We might as well mark the persist() method on
> our daos @transactional and remove the service layer.
>
> The only clean way to fix this seems to be either:
> (a) using DTO's so the UI/wicket is not actually modifying domain entities
>    upside: the state of the domain is not modified by wicket itself
>    downside: duplication of models (actual model + DTO);
>    downside: validation is currently set-up in wicket by scanning fields for
> validation annotations, so we would need to duplicate those on the DTO?
>
> (b) using a concept from CQRS: sending commands to the domain through a bus.
> This clearly and cleanly defines the intent and captures the exact change.
>    upside: the state of the domain is not modified by wicket itself
>    downside: likely overkill for what we are trying to achieve; lot of extra
> complexity
>
> (c) wrapping the entire request in a transaction
>    upside: easy to implement
>    downside: since anything in the request can fetch a dao, read some
> entities and modify them, this means we can lose track of what happens in a
> request;
>    downside: feels like moving backwards
>
> (d) simplify by removing thin services and, where necessary, putting more
> logic in the dao's
>    upside: simple api contract: want to save/update an entity? use the dao
> directly
>    downside: dao's contain logic which does not really belong there
>    downside: if at some point we really do need a service, the api contract
> becomes less clear: for X and Y you can use the dao, for Z you have to use a
> service
>
> (a) and (b) provide a way to capture a change and execute all of the change
> inside a transaction.
>
> So my question to the list is: what are your experiences with this? How do
> you deal with this in simple to moderately complex webapps?
>
> Thanks for reading!

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to