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


-- 
Alexander Snaps <[EMAIL PROTECTED]>
http://www.jroller.com/page/greenhorn
http://www.linkedin.com/in/alexandersnaps

Reply via email to