> Ok, and do you perform all such copying manually or do you use something
> automated for that? (Or simply a JPA merge?)

Yes, merge for simplicity, and if we have a custom caching mechanism
we simply replace the node object in a hashmap.

**
Martin

>
> Op 12-2-2012 16:22, schreef Martin Makundi:
>>
>> Yeah.. what we do is we detach entities when loading from service
>> layer to view layer and when user is ready to commit we persist them
>> on service layer overriding service layer state (standard locking
>> techniques here).
>>
>> **
>> Martin
>>
>> 2012/2/12 Bas Gooren<b...@iswd.nl>:
>>>
>>> Ok, so you mean detaching entities when returning them to the view layer
>>> (wicket)?
>>>
>>> How do you propose updating the underlying entities? Send the detached
>>> entities back to the service layer and copying their changes to attached
>>> entities? Or ...?
>>>
>>> Op 12-2-2012 14:22, schreef Martin Makundi:
>>>>
>>>> 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<b...@iswd.nl>:
>>>>>
>>>>> 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: users-unsubscr...@wicket.apache.org
>>>> For additional commands, e-mail: users-h...@wicket.apache.org
>>>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
>> For additional commands, e-mail: users-h...@wicket.apache.org
>>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
For additional commands, e-mail: users-h...@wicket.apache.org

Reply via email to