4

The Spring MVC binding mechanism is powerful, but I'm now confronted with a trivial issue that I wonder how to resolve:

  • User JPA entity, that is used for the binding and validation as well (i.e. throughout all layers)
  • "Edit profile" page, that is not supposed to change the password or some other entity properties

Two ways that I can think of:

  1. Using the same object

    • use @InitBinder to configure a list of disallowed properties
    • obtain the target user (by id)
    • then use a reflection utility (BeanUtils) to copy the submitted object to the target object, but ignore null values - i.e. fields that are not submitted
  2. Introduce a new object that has the needed subset of fields, and use BeanUtils.copyProperties(..) to merge it to the entity.

Alternatives?

3 Answers 3

2

I've found that as soon as your web model starts to diverge from your business layer in function, it's best to use a view layer object (a model object) to collect, or display the data

the entity:

public class com.myapp.domain.UserEntity {

}

the model object:

public class com.myapp.somesite.web.SomeSiteUserModel {

   public static SomeSiteUserModel from(UserEntity userEntity) {
      ... initialize model ...
   }

   public UserEntity getModelObject() {
      ... get entity back ... 
   }

}

now all view based operations can hand off processing to the internal model object if that makes sense, otherwise it can customize them itself. Of course the problem with this is you have to re-write all the getters and setters you want for the entity (an issue that I've had to deal with, that is annoying) unfortunately that is a bit of a Java language issue

Sign up to request clarification or add additional context in comments.

2 Comments

I ended up implementing it that way, just with a note that for "initialize model" I used BeanUtils.copyProperties(..)
very nice, I've had a need for something like that before, but had always ended up just doing it manually, thanks!
1

I just checked up with two of the last Spring projects I have worked on and in both places the following approach is taken:

In the JSP page for the form the change password field has a name that does not match the name of the password field in the User bean, so that it doesn't get mapped to the bean. Then in the onSubmit method there is a separate check whether a new password has been submitted, and if it has been, the change is reflected explicitly.

Поздрави, Vassil

4 Comments

thanks, the password-change will be handled by a simple request.gatPerameter(..), but there are many more properties of the User, that are not to be submitted / bound.
Well, in that case I think you have two choices: 1. Have all the properties' values output in the form (maybe using hidden fields for some). 2. Use an InitBinder - after all that's what they are meant for.
Using hidden fields means the user could submit different values for those fields, which is not what you want.
Well, this would mean that user input integrity had been compromised and handled by validation as invalid. The hidden fields are really a 'standard' hack implemented in a bunch of frameworks. I still like the init-binder solution better, though.
0

You can read the object from the database first and bind then the request. You can find an example at FuWeSta-Sample.

It uses a helper-bean which must be initialized by Spring.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.