在@RequestScoped bean上回发时保留GET参数

时间:2015-01-07 20:11:44

标签: jsf jsf-2

我希望仅在数据库中更新表单中指定的那些字段。在实体"帐户"我使用注释@DynamicUpdate

AccountMB@RequestScoped),方法为:

public String update() {
    getDao().update(getInstance());
    return SUCCESS;
}

public Account getInstance() {

    //setId(new Long("1"));

    if (instance == null) {
        if (id != null) {
            instance = loadInstance();
        } else {
            instance = createInstance();
        }
    }

    return instance;
}

并形成form.xhtml:

<f:metadata>
    <f:viewParam name="accountId" value="#{accountMB.id}" />
</f:metadata>

<h:form prependId="false">

    <h:inputHidden id="accountId" value="#{accountMB.id}"/>

    <h:inputHidden id="id" value="#{accountMB.instance.id}"/>

    <h:inputText id="firstName" value="#{accountMB.instance.firstName}"/>

    <h:commandButton type="submit" action="#{accountMB.update}" value="Save">
        <f:setPropertyActionListener target="#{accountMB.id}" value="1" />
    </h:commandButton> 
</h:form>

我打开页面form.xhtml?accountId=1,以加载的数据的形式,点击&#34;保存&#34;。它写了一个错误:

java.sql.SQLException: ORA-01407: cannot update ("MYBD"."ACCOUNTS"."EMAIL") to NULL

如果在getInstance()方法中取消注释setId(new Long("1"));,则会保存数据。

如果我在@ViewScoped中使用注释AccountMB,则会保存数据。

但我想使用注释@RequestScoped

我明白了,我触发了createInstance();并且电子邮件字段未填写。

告诉我如何将id传递给加载方法loadInstance();

我使用<f:setPropertyActionListener target="#{accountMB.id}" value="1" /><h:inputHidden id="accountId" value="#{accountMB.id}"/>。但这不起作用。请帮帮我。

1 个答案:

答案 0 :(得分:0)

你的错误是你(懒惰)在getter方法中加载实体而不是@PostConstruct。在JSF能够调用setId()之前,正在加载/创建实体。无论如何,在getter方法中执行业务逻辑是令人震惊的。 You'd better not do that and keep the getter methods untouched

如果您想使用@RequestScoped bean,<f:viewParam>对您来说并不十分有用。在@PostConstruct中准备实体为时已晚,因此可以填充提交的值。对于@ViewScoped bean,它可以正常工作,因为它在回发时被重用。

@RequestScoped bean中,您需要自己获取HTTP请求参数:

@Named
@RequestScoped
public class AccountBacking {

    private Account account;

    @EJB
    private AccountService service;

    @PostConstruct
    public void init() {
        String id = FacesContext.getCurrentInstance().getRequestParameterMap().get("accountId");
        account = (id != null) ? service.find(Long.valueOf(id)) : new Account();
    }

    public void save() {
        service.save(account);
    }

    public Account getAccount() {
        return account;
    }

}

然后你可以使用这个表单,只使用<f:param>来保留回发时的GET参数:

<h:form>
    <h:inputText id="firstName" value="#{accountBacking.account.firstName}"/>

    <h:commandButton action="#{accountBacking.save}" value="Save">
        <f:param name="accountId" value="#{param.accountId}" />
    </h:commandButton>
</h:form>