struts-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Adam Hardy <ahardy.str...@cyberspaceroad.com>
Subject Re: Fundamental flaw in Model-Driven?
Date Thu, 01 May 2008 14:51:13 GMT
Yes, you're right. There are also several other things lacking that I would find 
useful. But I guess it's still version 1.


Alexander Snaps on 01/05/08 15:35, wrote:
> Am I wrong, or JPA's EntityManager has no support for anything like
> evict()? I think this is an Hibernate's Session specific feature...
> Alex
> 
> On Thu, May 1, 2008 at 3:54 PM, Eric D Nielsen <nielsene@mit.edu> wrote:
> 
>> [ I suspect this is going to break threading....  Is there a good way to
>> respond
>> to a message from a digest without breaking threading? )
>>
>> Adam Hardy on 26/04/08 10:42, wrote:
>>> 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?
>> Unfortunately no.  First clear is overkill, it evicts everything from the
>> session, and only the model may need to be evicts (Users could have other
>> items
>> already merged back into the session at this point -- normally I would
>> have
>> merged my User entity from the HTTP Session to the Persistence session by
>> this
>> point in the interceptor stack to allow authentication/authorization
>> checks).
>>
>> Secondly replacing the clear() with evict(((ModelDriven)
>> action).getModel()) for
>> instance would avoid that problem, but now you would lost the ability to
>> lazy
>> load anything from the model if needed for form redisplay.
>>
>> I'm 90% of the way to an initial solution right now, using two extra
>> interceptors:
>> ModelDrivenProtection
>> ModelDrivenEnable
>> (I need better names....)
>>
>> The first one is placed in the stack after prepare.  The second one is
>> placed
>> after validation.
>>
>> In my Hibernate based implementation of them:
>> Protection calls session.setReadOnly(modelDrivenAction.getModel(),true) if
>> the
>> action also implements ValidationAware
>>
>> Enable calls session.setReadOnly(modelDrivenAction.getModel(),false) if
>>  hasErrors() returns false
>>
>> I'm hoping I can come up with a more JPA provider agnostic version, after
>> I get
>> this pair working.  However as the JPA spec doesn't include a notion of
>> readOnly, I think its going to have to be a custom version of the
>> JPAValidationInterceptor extends ValidationInterceptor--
>>
>> Steps are something like
>> doIntercept(...) {
>> if (actionInvocation.getAction() instanceof ValidationAware &&
>>     actionInvocation.getAction() instanceof ModelDriven) {
>>  ValidationAware validationAwareAction = (ValidationAware)
>> actionInvocation.getAction();
>>  ModelDriven modelDrivenAction = (ModelDriven)
>> actionInvocation.getAction();
>>  em.setFlushMode(FlushMode.COMMIT)
>>  String retVal = super.doIntercept(...);
>>  if (validationAwareAction.hasErrors()) {
>>    em.evict(modelDrivenAction.getModel());
>>    // check for preparable and recall prepare to get a clean object back
>> on the
>> stack -- need to make sure hasErrors() still returns true though....
>>    // push the request parameters onto the stack ahead of the model for
>> redisplay of submitted values, while letting the model fill in others)
>>  }
>>  em.setFlushMode(FlushMode.AUTO);
>>  return retVal;
>> }
>>
>> I like the hibernate version better since the "persistence read only" is
>> exactly
>> the correct semantics for a failed-validation model object.  The generic
>> JPA is
>> nicer in that its not vendor specific, but much more kludgy.  In rather
>> generalize it a bit more -- more the em.setFlushMode, em.evict calls to
>> some
>> interface and now we're to a more correct model driven situation:
>> a) the backing model object will never contain invalid values outside of
>> the
>> scope of params, validation, thisNewInterceptor (possibly built into
>> workflow
>> or validation)
>> b) values are still available for redisplay.
>> c) the three callback functions (setReadOnly, setWriteable, replaceModel)
>> or
>> similar can be hooked up to different backing stores... allowing any lazy
>> load
>> or other similar special behavior provided by the data store to work
>> transparently.
>>
>> This completely generalized version is the version that I would want to
>> suggest
>> for inclusion in Struts 2, but I'll need to work through the first two
>> approaches first to gain some confidence.
>>
>> Eric
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
>> For additional commands, e-mail: dev-help@struts.apache.org
>>
>>
> 
> 


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


Mime
View raw message