Java JSF selectitems值无效
假设我在xhtml页面上看到了这一点:Java JSF selectitems值无效,java,ajax,jsf,Java,Ajax,Jsf,假设我在xhtml页面上看到了这一点: <h:selectOneMenu value="#{repairManagerBean.manufacturerName}" id="manufacturer_selection"> <f:ajax listener="#{repairManagerBean.changeDevice}"
<h:selectOneMenu value="#{repairManagerBean.manufacturerName}"
id="manufacturer_selection">
<f:ajax listener="#{repairManagerBean.changeDevice}"
render="device_selection" />
<f:selectItems value="#{repairManagerBean.manufacturers}"
var="manufacturer" itemValue="#{manufacturer.name}"/>
</h:selectOneMenu>
<h:message for="manufacturer_selection" style="color: red"/>
<h:selectOneMenu value="#{repairManagerBean.deviceName}"
id="device_selection">
<f:selectItems value="#{repairManagerBean.devices}"
var="device" itemValue="#{device.name}"/>
</h:selectOneMenu>
<h:message for="device_selection" style="color: red"/>
<p><h:commandButton value="Submit" action="#{repairManagerBean.storeRepairInfo}" /></p>
并且不会调用storeRepairInfo方法
这是我的backing RepairManagerBean类:
@ManagedBean(name = "repairManagerBean")
@ViewScoped
public class RepairManager implements Serializable {
private Repair repair;
private List<Manufacturer> manufacturers;
private String manufacturerName;
private String deviceName;
private List<Device> devices;
/**
* Creates a new instance of RepairManagerBean
*/
public RepairManager() {
}
// getters and setters for all fields except daos
// Action Methods
public String storeRepairInfo() {
try {
Manufacturer m = manufacturerDao.findByName(manufacturerName);
Device d = deviceDao.findByName(deviceName);
repair.setDevice(d);
repair.setManufacturer(m);
saveRepair();
return "success";
} catch(Exception e) {
System.err.println("write fail");
return "error";
}
}
public void changeDevice(AjaxBehaviorEvent event) {
for(Manufacturer m : manufacturers) {
if(m.getName().equals(manufacturerName)) {
devices = deviceDao.findByManufacturerId(m.getId());
break;
}
}
}
@PostConstruct
public void init() {
repair = new Repair();
manufacturers = new ArrayList<>();
manufacturerName = "";
devices = new ArrayList<>();
deviceName = "";
try {
readManufacturersDevices();
} catch(Exception e) { System.err.println("manufacturers read fail");}
}
public void saveRepair() throws Exception {
// save repair object to db
}
public void readManufacturersDevices() throws Exception {
// normally ofc its read from db, but result is same here so you can compile it
Manufacturer apple = new Manufacturer(1l, "Apple");
Manufacturer myphone = new Manufacturer(2l, "myPhone");
manufacturers = new ArrayList<>();
manufacturers.add(apple);
manufacturers.add(myphone);
Device pocket2 = new Device(1l, "Pocket 2");
Device smartview7 = new Device(2l, "SmartView 7");
Device ipad4mini = new Device(3l, "iPad 4 mini");
Device iphone4 = new Device(4l, "iPhone 4");
devices = new ArrayList<>();
devices.add(pocket2);
devices.add(smartview7);
devices.add(ipad4mini);
devices.add(iphone4);
}
}
下面是简单的制造商实体类:
@Entity
@Table(name = "Device")
public class Device extends AbstractEntity {
@Column(name = "name")
private String name;
@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "manufacturer_id")
private Manufacturer manufacturer;
public Device() {
}
public Device(String name, Manufacturer manufacturer) {
this.name = name;
this.manufacturer = manufacturer;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Manufacturer getManufacturer() {
return manufacturer;
}
public void setManufacturer(Manufacturer manufacturer) {
this.manufacturer = manufacturer;
}
@Override
public String toString() {
return "Device{" + "id=" + id + "name=" + name + ", manufacturer="
+ manufacturer + '}';
}
@Override
public int hashCode() {
int hash = 7;
hash = 71 * hash + Objects.hashCode(this.name);
hash = 71 * hash + Objects.hashCode(this.manufacturer.getName());
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Device other = (Device) obj;
if (!this.name.equals(other.name)) {
return false;
}
if (!this.manufacturer.getName().equals(other.manufacturer.getName())) {
return false;
}
return true;
}
}
@Entity
@Table(name = "Manufacturer")
public class Manufacturer extends AbstractEntity {
@Column(name = "name")
private String name;
public Manufacturer() {
}
public Manufacturer(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Manufacturer{" + "id=" + id + "name=" + name + '}';
}
@Override
public int hashCode() {
int hash = 7;
hash = 29 * hash + Objects.hashCode(this.name);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Manufacturer other = (Manufacturer) obj;
if (!Objects.equals(this.name, other.name)) {
return false;
}
return true;
}
}
这里是简单的抽象实体:
@MappedSuperclass
public abstract class AbstractEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
正如您所看到的,我已经在设备实体类中实现了equals和hashcode。我在支持bean类上使用@ViewScoped。我也读了很多书和帖子。我不使用任何自定义转换器。谢谢您的帮助。所以问题是我的@PostConstruct init方法在每次表单操作后都重新初始化了所有字段。因此,在点击提交按钮后,它首先将设备和制造商设置回默认值(Apple),然后尝试使用错误的id将其保存到db。这是应该的:
@PostConstruct
public void init() {
try {
readManufacturersDevices();
} catch(Exception e) { System.err.println("manufacturers read fail");}
}
我也忘了getter for manufacturers list。还将@ViewScope从javax.faces.view更改为javax.faces.bean。。。。。总是。。。我敢打赌,这是解决方案1中的第一行:“确保在后续请求期间保留完全相同的列表,特别是在多个级联菜单的情况下。在大多数情况下,使bean
@ViewScoped
而不是@requestscope
应该可以修复它。”问题出在您尚未发布的java代码中。很可能由于某种原因,repairManagerBean.devices
被重置回苹果公司的设备列表。@VsevolodGolovanov我已经更新了我的问题,请。。。。请这不是一个很长的时间shot@VsevolodGolovanov您是否认为问题出在这一行:devices=deviceDao.findByManufacturerId(manufacturers.get(0.getId());大部分内容与您发布的第一个链接中的第1点有关。。。
@PostConstruct
public void init() {
try {
readManufacturersDevices();
} catch(Exception e) { System.err.println("manufacturers read fail");}
}