Re: [Stripes-dev] callback method prior to binding

Subject:   Re: [Stripes-dev] callback method prior to binding (find more)
From:  
Date:   Sep 21, 2005 12:55


Return-Path: <hidden>
Received: from tfenfen2 by esc49.midphase.com with local (Exim 4.44)
 id 1EI7sO-00013q-M9
 for hidden; Wed, 21 Sep 2005 12:55:20 -0400
Message-Id: <hidden>
Date: Wed, 21 Sep 2005 12:55:20 -0400
From: "Tim Fennell" <hidden>
Reply-To: hidden
Sender: hidden
To: hidden
Subject: Re: [Stripes-dev] callback method prior to binding
Errors-To: hidden
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
X-Original-To: hidden
Delivered-To: hidden
X-Mailer: NeoMail 1.27
X-IPAddress: 18.103.12.15
X-AntiAbuse: Sender Address Domain - tfenne.com
X-Source:
X-Source-Args:
X-Source-Dir:
X-Spam-Score: 0.0 (/)
X-Spam-Report: Spam Filtering performed by sourceforge.net.
 See http://spamassassin.org/tag/ for more details.
 Report problems to http://sf.net/tracker/?func=add&group_id=1&atid=200001
X-BeenThere: hidden
X-Mailman-Version: 2.0.9-sf.net
Precedence: bulk
List-Unsubscribe: <https://lists.sourceforge.net/lists/listinfo/stripes-development&gt;,
 <mailto:hidden?subject=unsubscribe>
List-Id: Mailing list for discussion of development of Stripes itself. <stripes-development.lists.sourceforge.net>
List-Post: <mailto:hidden>
List-Help: <mailto:hidden?subject=help>
List-Subscribe: <https://lists.sourceforge.net/lists/listinfo/stripes-development&gt;,
 <mailto:hidden?subject=subscribe>
List-Archive: <http://sourceforge.net/mailarchive/forum.php?forum=stripes-development>
Status:

I'm sure someone somewhere will have a violently negative reaction to what I'm about to
say :)

At work we have a whole suite of applications and code-bases that interact and are
presented to a user through a common UI framework.  We're using Hibernate and in some
places hand-coded JDBC.  We're using stateless session beans in EJB, an I think we even have
Spring in one of the applications.  We switched to hibernate 3.0 a while back (actually, shortly
before I started consulting here).  A lot of discussion was had about the new default of
objects being lazy, how to deal with this in the view tier etc.

Long story show, we went with the open-session-in-view pattern, and went one further.  We
call it the open-transaction-in-view pattern.  We have a servlet filter that initiates the
transaction, and determines whether to commit it (if no exception was thrown) or roll it back
(if an exception was thrown.  We also have a utility to grab the transaction and call
setRollbackOnly().  It may seem a little scary at first, but we really like it.  It's given us
practical solutions to all kinds of problems.  Previously we were trying to coordinate
transactions at the DAO level, and ran into all sorts of silly situations.  And the added
overhead of creating a transaction for read-only views is not even noticable.  Honestly it feels
like declarative transactions in EJB to me (which is one of the features I've always liked).

Anyway, probably not for everyone, but it's working for us.

-t



> Hey Greg,
>
> I think your approach is a good one.  You also eliminate the need for a
> "preEdit" method to re-hydrate the object since your setContext() method
> takes care of this in all cases. Nice.
>
> You also point out something that some less experienced developers may
> have overlooked.  If you are using an O/R Mapper such as Hibernate, you
> need to be aware of where [Hibernate] sessions and transactions begin
> and end.  In your example, you use a servlet filter to open a Hibernate
> session and [presumably] place it in thread local.  This way, you are
> retrieving and modifying the object in the SAME Hibernate session (which
> is an appropriate discipline that is often ignored).  This is why you
> must rollback if validation fails.  You don't want to update the
> underlying data store in the event of a validation error.  For Spring
> users, you can implement Greg's strategy by using the OpenSessionInView
> filter or interceptor (see docs for configuration info).
>
> The other consideration is transaction demarcation.  If your Dao method
> is wrapped in a transaction (for example, via an AOP transaction proxy
> in Spring), then things can start to get a little tricky with the
> OpenSessionInView strategy.  Remember, a hibernate "session" is not the
> same as a "transaction".  If your save method calls a transactional DAO
> method that performs multiple database operations, then you must be
> completely aware of the ramifications if a failure occurs in either the
> web tier (during the session) or the business tier (during the session
> AND transaction).   This is one reason why I haven't completely embraced
> the OpenSessionInView strategy for all situations.  Unfortunately, the
> only realistic option that allows you to synchronize your hibernate
> session and transactions is to "break" the connection between objects
> updated by the web tier and the domain objects.  In other words, this
> leads you back to the path of using some sort of Data Transfer Object to
> marshal object values (or by putting all the inserted/updated attributes
> on the method signature).  This way, you are retrieving the "real"
> object and updating the values inside a method that is wrapped by a
> session AND a transaction.
>
> The appropriate approach is really dependent on the situation (as
> always).  I am simply pointing out some things to be aware of.
>
> Dan.
>
>
> Greg Hinkle wrote:
>
> > Yea, Tim is right. I've been pretty successful integrating stripes  
> > and Hiberate by using two parts. I bind the object to be edited in  
> > the setContext method and use validation error handling for the  
> > rollback. I'm using a servlet filter for session management so this  
> > works nicely. I'll include my response on exactly what I do that I  
> > sent to the user list below. I thought about creating special support  
> > for this type of work in the framework or an extension, but then  
> > realized that its a base class and maybe two extra lines of code. If  
> > we could get it to the point where all basic CRUD comes free for  
> > hibernate objects, I might be interested in an extra annotation and  
> > framework handling that could worry about key binding, loading and  
> > CRUD, etc.
> >
> >
> >
> > There is no good way to have the id set first so I do my entity setup
> > in the setContext method of ActionBean. This happens before any
> > binding so if I setup my entity here, the bindings will happen
> > against that entity. This also means I have to rollback the
> > transaction if any part of validation fails. That can be done by
> > having your ActionBean implement the ValidationErrorHandler interface
> > and doing the rollback. By conditionally looking up the id if it
> > exists, I can use the same ActionBean for all CRUD operations on my
> > User enttiy. Examples below.
> >
> >      public void setContext(ActionBeanContext context) {
> >          this.context = context;
> >          String id = context.getRequest().getParameter("user.id");
> >          if (id != null) {
> >              user = new UserDAO().getUser(new Long(id));
> >          }
> >      }
> >
> >
> >      public Resolution handleValidationErrors(ValidationErrors  
> > errors) throws Exception {
> >          HiberUtil.rollbackTransaction();
> >          return null;
> >      }
> >
> >
> >
> >
> > On Sep 19, 2005, at 7:09 PM, James Stangler wrote:
> >
> >> I'd like to echo a request for a feature similar to this.  I've  just
> >> started using Stripes and
> >> really like the amount of functionality available for the  simplicity
> >> of the design.  I'll probably
> >> have a bunch of feedback and suggestions as I work more with it.
> >>
> >> I too would like a mechanism to either rebind the parameters to the  
> >> object or have more control
> >> over when validation and binding happens.  Perhaps have some  prebind
> >> method annotation or a way to
> >> reinvoke the binding.  One thing that I struggle with is that  
> >> validation and binding happen at the
> >> same time (as I understand), so that if validation fails half way  
> >> through, some of the binding has
> >> already been performed.  If the binding stores values in a  hibernate
> >> object, I've corrupted a
> >> hibernate object that must be cleared from the hibernate cache  
> >> unless I know that the user will
> >> resubmit with valid values.  Or perhaps there's a better way that  
> >> I'm not familiar with.  The
> >> gui/presentation layer was never my strong point.
> >>
> >> jim
> >>
> >> --- Tim Fennell <hidden> wrote:
> >>
> >>
> >>> Hey Dan,
> >>>
> >>> Greg's actually been doing a decent amount of work with Stripes
> >>> +Hibernate.  The solution he came up with is to use the setContext()
> >>> method as that intercept point.  The way the life-cycle works, the
> >>> setContext method is always called before any other binding happens,
> >>> in case the ActionBean needs access to context information to behave
> >>> appropriately.  So, what he's been doing is adding a little code in
> >>> setContext() that fetches the appropriate request parameters, looks
> >>> up the persistent object using it and then attaches it to the
> >>> ActionBean prior to binding proceeding.  I think that fits with what
> >>> you're looking for.
> >>>
> >>> I'm actually in the market for a good pattern to make this a it more
> >>> general and easier to handle.  I was thinking it would be nice to
> >>> provide an extended binder for use with Hibernate (or conceivable
> >>> other persistence tiers) that manages the hooking up of objects by
> >>> ID.  But it's tough to come up with a pattern that doesn't break down
> >>> pretty rapidly...  If you have any ideas I'd be glad to hear them :)
> >>>
> >>> -t
> >>>
> >>>
> >>> On Sep 19, 2005, at 5:30 PM, Dan Hayes wrote:
> >>>
> >>>
> >>>> Tim,
> >>>>
> >>>> I sending this to the mailing list as there may be others
> >>>> interested in the dialogue....
> >>>>
> >>>> I'm running into a bit of a request lifecycle issue when editing a
> >>>> bean that is nested in the ActionBean.  Currently in Stripes there
> >>>> is no call back or hook to "re-hydrate" an object PRIOR to binding
> >>>> request parameters.  This is a problem as when there are attributes
> >>>> of a bean that are not exposed to the user interface for direct
> >>>> editing (they may be complex types that are not directly updatable
> >>>> via this user interaction or simply attributes that have no
> >>>> consequence to the user such as createdDate, createdUser, etc).
> >>>>
> >>>> Let's say you have an ActionBean with property of the type Foo.
> >>>> Foo is an object with many attributes including a createdBy
> >>>> property.  This attribute is not (and shouldn't be) exposed in the
> >>>> form, or as a hidden field. However, when the form is posted, the
> >>>> binding mechanism creates a new Foo and applys the request
> >>>> parameters (assuming this is not SessionScope).  CreatedBy is null
> >>>> at this time.  In the event handler for "save", the DAO is passed
> >>>> the Foo object for persistence (I typically use Hibernate).
> >>>> Unfortunately, the database will either have empty data in the
> >>>> createdBy field or balk if a constraints exist.
> >>>> What is lacking is some sort of callback method on the ActionBean
> >>>> so that you could re-hydrate the full object PRIOR to the binding
> >>>> mechanism applying the parameters.  I tried to think of an easy way
> >>>> but I'm drawing a blank.  Ideally, you would want to do this only
> >>>> on processing of a form submission but I am fearful of complicating
> >>>> things.
> >>>> Spring has a method called formBackingObject() that is called on
> >>>> every request (unless it is session scope).  That is where is used
> >>>> to pick up the object from the store prior to Spring binding.
> >>>>
> >>>> Ideas???
> >>>>
> >>>> By the way, the layout stuff works great and I have retro-fitted my
> >>>> current project with it (removing sitemesh).
> >>>>
> >>>> Dan.
> >>>>
> >>>> --
> >>>> Dan Hayes
> >>>> Chariot Solutions, LLC
> >>>> hidden
> >>>> 610-716-2292
> >>>>
> >>>>
> >>>>
> >>>> -------------------------------------------------------
> >>>> SF.Net email is sponsored by:
> >>>> Tame your development challenges with Apache's Geronimo App Server.
> >>>> Download
> >>>> it for free - -and be entered to win a 42" plasma tv or your very  own
> >>>> Sony(tm)PSP.  Click here to play: http://sourceforge.net/ geronimo.php
> >>>> _______________________________________________
> >>>> Stripes-development mailing list
> >>>> hidden
> >>>> https://lists.sourceforge.net/lists/listinfo/stripes-development
> >>>>
> >>>>
> >>>
> >>>
> >>>
> >>> -------------------------------------------------------
> >>> SF.Net email is sponsored by:
> >>> Tame your development challenges with Apache's Geronimo App  Server.
> >>> Download
> >>> it for free - -and be entered to win a 42" plasma tv or your very own
> >>> Sony(tm)PSP.  Click here to play: http://sourceforge.net/geronimo.php
> >>> _______________________________________________
> >>> Stripes-development mailing list
> >>> hidden
> >>> https://lists.sourceforge.net/lists/listinfo/stripes-development
> >>>
> >>>
> >>
> >>
> >>
> >>
> >> __________________________________
> >> Yahoo! Mail - PC Magazine Editors' Choice 2005
> >> http://mail.yahoo.com
> >>
> >>
> >> -------------------------------------------------------
> >> SF.Net email is sponsored by:
> >> Tame your development challenges with Apache's Geronimo App Server.  
> >> Download
> >> it for free - -and be entered to win a 42" plasma tv or your very own
> >> Sony(tm)PSP.  Click here to play: http://sourceforge.net/geronimo.php
> >> _______________________________________________
> >> Stripes-development mailing list
> >> hidden
> >> https://lists.sourceforge.net/lists/listinfo/stripes-development
> >>
> >
> >
> >
> > -------------------------------------------------------
> > SF.Net email is sponsored by:
> > Tame your development challenges with Apache's Geronimo App Server.
> > Download
> > it for free - -and be entered to win a 42" plasma tv or your very own
> > Sony(tm)PSP.  Click here to play: http://sourceforge.net/geronimo.php
> > _______________________________________________
> > Stripes-development mailing list
> > hidden
> > https://lists.sourceforge.net/lists/listinfo/stripes-development
> >
> >
>
> --
> Dan Hayes
> Chariot Solutions, LLC
> hidden
> 610-716-2292
>
>
>
> -------------------------------------------------------
> SF.Net email is sponsored by:
> Tame your development challenges with Apache's Geronimo App Server. Download
> it for free - -and be entered to win a 42" plasma tv or your very own
> Sony(tm)PSP.  Click here to play: http://sourceforge.net/geronimo.php
> _______________________________________________
> Stripes-development mailing list
> hidden
> https://lists.sourceforge.net/lists/listinfo/stripes-development
>
>




-------------------------------------------------------
SF.Net email is sponsored by:
Tame your development challenges with Apache's Geronimo App Server. Download
it for free - -and be entered to win a 42" plasma tv or your very own
Sony(tm)PSP.  Click here to play: http://sourceforge.net/geronimo.php
_______________________________________________
Stripes-development mailing list
hidden
https://lists.sourceforge.net/lists/listinfo/stripes-development