我正在寻找好的做法和干净的解决方案来解决我的问题。有2个实体类:
@Entity
public class Site implements Serializable {
...
@OneToMany(mappedBy = "site")
private List<SiteIp> siteIpList;
...
public List<SiteIp> getSiteIpList() {
return siteIpList;
}
public void setSiteIpList(List<SiteIp> siteIpList) {
this.siteIpList = siteIpList;
}
}
@Entity
@IdClass(SiteIpPK.class)
public class SiteIp implements Serializable {
@Id
@ManyToOne(fetch = FetchType.LAZY)
private Site site;
@Id
private int idx;
private String ip;
/* other stuff such as constructors, getters and setters */
}
SiteIpPK 有 2 列,应该是干净的 :) 显然,这是世界上常用的模型。
接下来,有一个视图层。JSF 页面有 3 个字段显示给定站点和 idx 的 SiteIp.ip。到目前为止,我已经在 Site 实体上编写了 helper getter 方法:
public String getIpForIdx(Integer idx) {
// there's no simple siteIpList.get(idx), because of additional logic in getter
// so let's iterate through entire list
for (SiteIp siteIp : this.siteIpList) {
if (/* other logic returns true value && */ siteIp.getIdx() == idx) {
return siteIp.getIp();
}
}
return null;
}
JSF 表达式语言的构造如下:
<h:inputText id="sync1_ip" value="#{siteController.editContext.site.getIpForIdx(1)}" />
现在,当页面被访问时,正确的 IP 值被传播到输入文本字段,到目前为止一切都很好。但是,当 IP 更改并提交表单时,EL 会抛出异常:
javax.el.PropertyNotWritableException: /edit/siteEdit.xhtml @47,123 value="#{siteController.editContext.site.getIpForIdx(1)}": Illegal Syntax for Set Operation
我理解并承认这一点,所以我的问题是:
处理此问题的最佳做法是什么?有点糟糕的解决方案是编写与存在唯一索引一样多的辅助方法:
public String getIp1() {
return this.IpForIdx(1);
}
public String getIp2() {
return this.IpForIdx(2);
}
/* ... */
public void setIp1(String newIp) {
this.siteIpList.add(1, newIp);
}
public void setIp2(String newIp) {
this.siteIpList.add(2, newIp);
}
/* ... and so on... */
使用 JSF EL:
<h:inputText id="sync1_ip" value="#{siteController.editContext.site.ip1}" />
还有其他更灵活、更美观的解决方案吗?