Return-Path: <hidden>
Received: from unknown (HELO ?10.0.1.135?) (
hidden@127.0.0.1)
by localhost with SMTP; 21 Sep 2005 07:40:19 -0700
Message-ID: <hidden>
Date: Wed, 21 Sep 2005 10:40:39 -0400
From: Dan Hayes <hidden>
Reply-To: hidden
Sender: hidden
To: hidden
Subject: Re: [Stripes-dev] callback method prior to binding
In-Reply-To: <hidden>
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
User-Agent: Mozilla Thunderbird 1.0 (Windows/20041206)
X-Accept-Language: en-us, en
References: <hidden> <hidden>
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>, <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>, <mailto:hidden?subject=subscribe>
List-Archive: <
http://sourceforge.net/mailarchive/forum.php?forum=stripes-development>
Status:
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