When you want to modify just a "part" of an object, you need to be
sure that you load the model from the database *before* you apply the
parameters posted from your web form. What is happening is that your
form is creating a *new* user instance and populating the fields from
your small form (id, name, etc) and then updating the database.
Typically, this is done using the Preparable interface on your action
in Struts. In prepare() you look for the id of the object and you
try and load it from the database. The tricky part has to do with
Struts2 interceptors. The two interceptors we are concerned with are
params and prepare. If you look at struts.xml you will see a list of
interceptors defined as a "stack". In this list you will see prepare
and then you will see params later on. The prepare interceptor checks
to see if your object implements Preparable and calls prepare() if it
does. The param interceptor takes the parameters posted in the
request and applies them to the various setters on your action. What
makes this tricky is that we have a setter called setId() that we need
to be called *before* prepare in order to know what object to load.
The solution is to add another reference to params interceptor before
prepare. The net effect is that Struts will apply all the parameters
from your post, then call prepare and load the object from the
database (overwriting the post values), and then Struts will write the
post values again, only overwriting what you have posted and keeping
the older values from the database. In this example you can also look
for user.getId() in prepare, but you'd have to check to see if user is
null.
So that is how it was done in Struts for thousands of years. Now in
the lastest versions of Appfuse, Matt has come with a rather nice
solution using prepare. In his example you don't need to add the
extra run of the params interceptor before prepare because he works on
the raw request. This is some nice code, that gets around a rather
painful pattern in Struts. The only complaint I would have is making
your action http dependent. Its is considered bad form to have your
action work with HTTP elements like HttpServletRequest or
HttpServletSesssion directly. There are plans to correct this in the
near future by using Struts built in support like RequestAware or
SessionAware that return a plain map connected by Struts to the HTTP
object.
public void prepare() {
if (getRequest().getMethod().equalsIgnoreCase("post")) {
// prevent failures on new
if (!"".equals(getRequest().getParameter("user.id"))) {
user =
userManager.getUser(getRequest().getParameter("user.id"));
}
}
}
So the moral is follow Matt's pattern. Unless you plan to submit
EVERY SINGLE field for a model when you save or update then its a good
idea to get this prepare() pattern to be part of your muscle
memory. ;-)
On Apr 1, 2008, at 3:12 AM, tibi wrote:
hi list,
im not sure how to update an user when i only want to update one or
two
fields.
using struts spring hibernate
lets say i only want to change the name.
i make a form with hidden field with id and a normal field with name.
when i enter my save method i have a user with only an id and name.
and
the other fields like password version etc. are empty.
should i get the old userfrom the db and copy the name from the new
one
to the old one and update it??
should i put all fields hidden in my form?
should i save the user into the session?
thanks,
tibi
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]