在selectOneMenu中的五个选项中,我选择了第二个选项并保留了实体。在编辑持久化实体时,selectOneMenu总是以最后一个选项作为其值。
例如,<h:selectOneMenu value="#{userHome.user.leader}">
<f:selectItems value="#{userHome.availableLeaders}" var="leader" itemLabel="# {leader.name}" itemValue="#{leader}"/>
</h:selectOneMenu>
where availableLeaders是一个用户列表填充@PostConstruct方法
我希望selectOneMenu有第二个选项(选择)在编辑。
@FacesConverter(forClass = User.class, value = "userConverter")
public class UserConverter implements Converter {
public UserConverter() {
}
@Override
public Object getAsObject(FacesContext context, UIComponent component,
String value) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("DefaultPersistenceUnit");
EntityManager em = emf.createEntityManager();
Query q = em.createQuery("select query");
return q.resultList().get(0);
}
@Override
public String getAsString(FacesContext context, UIComponent component,
Object value) {
return ((User) value).getName();
}}
在User.java public boolean equals(Object other) {
if (this.getClass().isInstance(other)) {
return true;
} else {
return false;
}
}
public int hashCode() {
HashCodeBuilder builder = new HashCodeBuilder();
builder.append(getId());
builder.append(getName());
return builder.toHashCode();
}
看这里:
public boolean equals(Object other) {
if (this.getClass().isInstance(other)) {
return true;
} else {
return false;
}
}
你的equals()
方法肯定是坏的。这对于每个其他User
对象返回true
,即使它内部持有一个完全不同的用户ID/名称。因此所选项目匹配每个可用的选择项目值。这就是为什么你每次都会看到最后一个项目被预选。
假设id
属性对于每个用户都是唯一的,那么equals()
方法最简单的样子应该是这样的:
public boolean equals(Object other) {
if (!(other instanceof User)) {
return false;
}
if (other == this) {
return true;
}
if (id != null) {
return id.equals(((User) other).id);
}
return false;
}
也可以总结如下
public boolean equals(Object other) {
return (other instanceof User) && (id != null) ? id.equals(((User) other).id) : (other == this);
}
提示:有点像样的IDE像Eclipse可以自动生成equals()
(和hashCode()
)方法。
参见:
- 平等合同的正确实施方式
- equals和hashCode的通用反射辅助方法