我希望仅在数据库中更新表单中指定的那些字段。在实体"帐户"我使用注释@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}"/>
。但这不起作用。请帮帮我。
答案 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>