[prev in list] [next in list] [prev in thread] [next in thread] 

List:       struts-dev
Subject:    Re: Fundamental flaw in Model-Driven?
From:       Adam Hardy <ahardy.struts () cyberspaceroad ! com>
Date:       2008-04-30 22:42:23
Message-ID: 4818F5CF.2000508 () cyberspaceroad ! com
[Download RAW message or body]

Adam Hardy on 26/04/08 10:42, wrote:
> Jeromy Evans on 26/04/08 04:51, wrote:
>> Eric D Nielsen wrote:
>>> I've been investigating some interesting behavior regarding model-driven
>>> actions and found a past thread that covers the situation from late last
>>> year:
>>>
>>> http://www.nabble.com/ModelDriven-CRUD-validation-failure-still-causes-JPA-update-td12987242.html 
>>> ...
>>>
>>> It would seem to be a way forward exists, however. Model Driven can be
>>> tweaked as follows:
>>>   The model driven interceptor would need to
>>> a) capture the raw request parameters into some storage
>>> b) skip the second params interceptor
>>> c) create a copy of the getModel object  (to ensure its detached from 
>>> any
>>> persistence session -- need to make sure this works for other common
>>> persistence engines)
>>> d) run params/validation on this copy
>>> e) if no validation errors, run params on the orginal (still attached 
>>> to the
>>> persistence session), and proceed as normal
>>> f) if validation errors, intercept calls to the getters for values in 
>>> the raw
>>> request for redisplay -- need to worry about XSS issues here
>>>
>>> There's a lot of moving pieces, and I'm sure I'm missing some even more
>>> subtle interactions. However I do think something needs to be done. 
>>> I'm interesting in tackling this, and am hoping for some feedback on 
>>> the above
>>> outline of required changes.
>>>   
>> Hi Eric,
>> I haven't had an opportunity to absorb your suggestion properly yet 
>> but thought I'd mention I agree with your line of thinking that the 
>> validation mechanism in particular needs to be improved. However, this 
>> is a general problem that also applies to rich clients; that is 
>> responsibility for rolling back changes to a model, and various 
>> patterns have developed over the years.  A temporary copy is a simple 
>> implementation, however within a JPA-environment automatically 
>> creating a clone is often infeasible or undesirable. For example, if 
>> it's attached to a session, this process may cause hydration of the 
>> entire object graph. Unless the framework is provided hints, it won't 
>> know what to safely/efficiently clone.
>>
>> Having the framework maintain dirty flags or proxy for the model also 
>> seems ineffective as the JPA provider performs the exact same task, 
>> only better.
>>
>> The option to write straight to the model (or DTO) and performing 
>> validation of the model (or DTO) is a distinguishing feature of Struts 
>> 2, but also the source of such complications. Anyway, I don't have a 
>> solution, but I do intend to start resolving the numerous validation 
>> issues in JIRA in the near future and this one is the list.
> 
> I also stumbled across this problem.
> 
> One solution could be to use a TypeConverter to instantiate new, 
> unmanaged entities during the ParamsInterceptor invocation.
> 
> Such a TypeConverter could pass back instantiated, blank entities (with 
> nothing but the ID) for ParamsInterceptor to collate, and against which 
> ValidationInterceptor can operate. E.g. for param 'bean=69', the type 
> converter instantiates Bean and calls setId(69)
> 
> Once Validation succeeds, ModelDriven and ParamsInterceptor should be 
> invoked again to update the managed entities.
> 
> The unmanaged entities would just disappear out of scope and be garbage 
> collected.
> 
> Such a strategy would require modification to ParamsInterceptor to tell 
> it to use the initial TypeConverter on the first call, but not on the 
> second. Whether the algorithm that controls that is accessible for 
> modification in the ParamsInterceptor or whether it is out-of-reach in 
> OGNL somewhere, I'm not sure.

I am pulling in what I wrote earlier because I should correct what I said about 
letting entities slip out of scope. Following this situation:

- Model-driven builds the model
- conversion to type and setting incoming HTTP param into Model
- validation occurs and fails

the problem was spurious JPA updates - which can be avoided by putting an 
interceptor in between the Validation and the Workflow interceptors: all it 
should do is call EntityManager.clear().

if (validationAwareAction.hasErrors()) getEntityManager().clear();


Using the JPA extended persistence context (not EJB), the clear() will eliminate 
any changes to the model before JPA comes to flush to the db. I assume it would 
work in an EJB container too.

Does that fit your situation, Eric?

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic