Проблема в том, что ваш h:commandButton
создает новый запрос к серверу, что заставляет UserBean
создавать новый экземпляр самого себя в области действия Request
.
Есть несколько решений, о которых я могу подумать.
1)
Кажется, вы знаете, находится ли ваша страница в режиме редактирования или нет. Затем вы можете избавиться от preRender method
и вместо этого получить userObj
из базы данных при вызове метода получения userObj
. Затем вы можете перейти на ваш add method
, если ваша страница находится в режиме редактирования или нет. Поэтому вам необходимо изменить commandButton
: (примечание: вы должны изменить значение на текущий режим редактирования)
<h:commandButton value="#{user.buttonTitle}" action="#{user.addUser}" style="width: 105px; ">
<f:setPropertyActionListener value="true" target="#{user.editUser}" />
</h:commandButton>
и ваш userBean
до:
@Component("user")
@Scope("request")
public class UserBean {
private User userObj;
private boolean editUser;
public String addUser() throws Exception {
userObj = getUserObj();
if (editUser) {
userService.updateUser(userObj);
} else {
userService.addUser(userObj);
}
return "users?faces-redirect=true";
}
public void setEditUser(boolean editUser) {
this.editUser = editUser;
}
public User getUserObj() {
if (editUser) {
if(userObj == null) {
userObj = userService.getUser(userID);
}
return userObj;
}
else {
return userObj = new User();
}
}
public void setUserObj(User userObj) {
this.userObj = userObj;
}
Это должно дать вам базовое представление о том, как это работает. Хитрость заключается в использовании f:setPropertyActionListener
.
2) Вы можете использовать область просмотра для решения этой проблемы. Проблема в том, что весна не предлагает это из коробки. Хорошей новостью является то, что вы можете создать область просмотра самостоятельно. Вот посмотрите на это сообщение в блоге .