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]


Reply via email to