Jsf使用旧值更新模型值

时间:2010-08-04 18:03:12

标签: java jsf lifecycle

我在更新到正确值时遇到了一些问题。在您可以看到部分下方的页面上,有一个参数'change'。我认为这个参数导致jsf用旧值更新支持bean,因此什么都不做。

<h:panelGroup id="panel0">
            <h:form id="changeForm">
                <h:messages/>
                <!--This retains the parameter "change"-->
                <input type="hidden" name="change" value="#{param.change}"/>
                <!--CHANGE NAME-->
                <h:panelGrid id="panel1" rendered="#{param.change == 'name'}" columns="2">
                    First Name:
                    <h:inputText id="firstName" value="#{changeInfoBean.firstName}"/>
                    Last Name:
                    <h:inputText id="lastName" value="#{changeInfoBean.lastName}"/>
                     <f:facet name="footer">
                        <h:panelGroup style="display:block; text-align:center">
                            <h:commandButton value="Submit Name" action="#{changeInfoBean.changeName}"/>
                        </h:panelGroup>
                    </f:facet>
                </h:panelGrid>
          </h:form>
    </h:panelGroup>

我也尝试将两个inputText字段设置为immediate =“true”,但这也不起作用。

我的支持豆:

@Named(value="changeInfoBean")
@SessionScoped
public class ChangeInfoBean {

    private String email;
    private String firstName;
    private String lastName;

    /** Creates a new instance of ChangeInfoBean */
    public ChangeInfoBean() {
            FacesContext context = FacesContext.getCurrentInstance();
            // Gets the user which is currently logged in
            LoginBean bean = (LoginBean) context.getExternalContext().getSessionMap().get("loginBean");
            BasicUser user = bean.getUser();
            this.email = user.getEmail();
            this.firstName = user.getFirstName();
            this.lastName = user.getLastName();

    }

    public void changeName() {
        Session session = null;
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            Transaction tx = session.beginTransaction();
            String hql = "update BasicUser set firstName = :newFirstName, lastName = :newLastName "
                    + "where email = :email";
            Query query = session.createQuery(hql);
            query.setString("newFirstName", this.firstName);
            query.setString("newLastName", this.lastName);
            query.setString("email", this.email);
            int rowCount = query.executeUpdate();
            tx.commit();
            System.out.println("Rows affected: " + rowCount);
            }
            catch(Exception e) {
                e.printStackTrace();
            }
            finally {
                session.close();
            }
    }
    public String getLastName() {
        System.out.print("I am getting my lastName: " + this.lastName);
        return lastName;
    }

    public void setLastName(String lastName) {
        System.out.print("I am updating my lastName to: " + this.lastName);
        this.lastName = lastName;
    }
}

当我尝试将我的lastName从Lindhardt更改为新的时候我得到了这个

INFO: START PHASE RESTORE_VIEW 1
INFO: END PHASE RESTORE_VIEW 1
INFO: START PHASE APPLY_REQUEST_VALUES 2
INFO: END PHASE APPLY_REQUEST_VALUES 2
INFO: START PHASE PROCESS_VALIDATIONS 3
INFO: I am getting my lastName: Lindhardt
INFO: END PHASE PROCESS_VALIDATIONS 3
INFO: START PHASE UPDATE_MODEL_VALUES 4
INFO: I am updating my lastName to: Lindhardt
INFO: END PHASE UPDATE_MODEL_VALUES 4
INFO: START PHASE INVOKE_APPLICATION 5
INFO: Hibernate: update coffeedrinkers.basic_user set First_Name=?, Last_Name=? where Email=?
INFO: Rows affected: 1
INFO: END PHASE INVOKE_APPLICATION 5
INFO: START PHASE RENDER_RESPONSE 6
INFO: I am getting my lastName: Lindhardt
INFO: END PHASE RENDER_RESPONSE 6

因此,支持bean永远不会收到新的lastName,只是使用旧的lastName更新模型。这不奇怪:)

1 个答案:

答案 0 :(得分:2)

使用this您引用当前实例的变量,而不是本地(传入)变量。您在使用传入变量设置之前打印当前实例的变量,而您感兴趣的是传入的变量。

public void setLastName(String lastName) {
    System.out.print("I am updating my lastName to: " + this.lastName);
    this.lastName = lastName;
}

将其更改为

public void setLastName(String lastName) {
    System.out.print("I am updating my lastName to: " + lastName);
    this.lastName = lastName;
}

public void setLastName(String lastName) {
    this.lastName = lastName;
    System.out.print("I am updating my lastName to: " + this.lastName);
}

它会打印出正确的。


更新:根据评论,上述内容仅部分解决了问题。毕竟,仍然存在/重新显示错误的值。这似乎与CDI的@Named注释有关。它导致bean在JSF生命周期的每个阶段都看似共鸣。用JSF标准@ManagedBean注释替换它确实解决了这个问题。