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: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]