У меня есть PrimeFaces 3.5, JSF 2.2, Hibernate 4 веб-приложение.PrimeFaces не может получить логическое значение из выделенной строки dataTable
home.xhtml содержит вкладку с вложенными dataTables для трех объектов (пользователи, компьютер, приложения) и кнопки добавления/редактирования/удаления. Каждая кнопка должна вызывать диалог с кнопками формы и отправки/отмены.
Проблема заключается в том, что я не могу корректно отображаться логическое значение (licenseRequired) от selectedApplication при попытке изменить его таким же образом, как это было установить, я получаю сообщение:
/pages/home.xhtml @424,149 value="#{homeBean.selectedApplication.licenseRequired}": Target Unreachable, 'selectedApplication' returned null
Если удалить кусок кода, который отвечает за licenseRequired поле, все работает правильно и получить другие выбранные значения без каких-либо проблем:
Вот диалог формы, что приводит к NPE на этом поле:
<p:dialog id="editAppDialog" header="Edit" draggable="true" closable="false" modal="true"
widgetVar="dlg6" width="600" >
<h:form id="dlg6form">
<h:panelGrid id="panel6" columns="3">
<h:outputLabel for="appName2" value="Name: "/>
<p:inputText id="appName2" required="true" value="#{homeBean.selectedApplication.appName}"
label="Name">
<f:validator binding="#{uniqueApplicationValidator}"/>
</p:inputText>
<p:message for="appName2"/>
<h:outputLabel for="vendorName2" value="Vendor: "/>
<p:inputText id="vendorName2" value="#{homeBean.selectedApplication.vendorName}"
label="Vendor" required="true" />
<p:message for="vendorName2"/>
<h:outputLabel for="appLicense2" value="Requires license: "/>
<p:selectOneMenu id="appLicense2" required="true" style="width: 80px;" value="#{homeBean.selectedApplication.licenseRequired}" >
<f:selectItem itemLabel="true" itemValue="#{true}" />
<f:selectItem itemLabel="false" itemValue="#{false}" />
</p:selectOneMenu>
<p:message for="appLicense2"/>
</h:panelGrid>
<p:commandButton type="button" value="Cancel" onclick="dlg6.hide()" />
<p:commandButton value="OK" process="@form" update=":dlg6form:panel6, :tab:applications" action="#{homeBean.editApplication}"
oncomplete="if (args && !args.validationFailed) dlg6.hide()"/>
</h:form>
</p:dialog>
Application.java:
@Entity
@Table(name="applications", catalog="adminportal")
public class Application implements Serializable {
@Id @GeneratedValue(strategy=IDENTITY)
@Column(name="app_id", unique=true, nullable=false)
private Integer appId;
@Column(name="app_name", nullable=false)
private String appName;
@Column(name="vendor_name", nullable=false)
private String vendorName;
@Column(name="license_required", nullable=false, columnDefinition = "BIT", length = 1)
private boolean licenseRequired;
@OneToMany(fetch=FetchType.LAZY, mappedBy="applications")
private Set<ComputerApp> computerApps = new HashSet<>(0);
public Integer getAppId() {
return appId;
}
public void setAppId(Integer appId) {
this.appId = appId;
}
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getVendorName() {
return vendorName;
}
public void setVendorName(String vendorName) {
this.vendorName = vendorName;
}
public Set<ComputerApp> getComputerApps() {
return computerApps;
}
public void setComputerApps(Set<ComputerApp> computerApps) {
this.computerApps = computerApps;
}
public boolean isLicenseRequired() {
return licenseRequired;
}
public void setLicenseRequired(boolean licenseRequired) {
this.licenseRequired = licenseRequired;
}
}
HomeBean.java:
package com.infostroy.adminportal.controller.bean;
import com.infostroy.adminportal.bean.BaseBean;
import com.infostroy.adminportal.model.Application;
import com.infostroy.adminportal.model.Computer;
import com.infostroy.adminportal.model.User;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import javax.annotation.PostConstruct;
import org.primefaces.context.RequestContext;
import org.primefaces.event.SelectEvent;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("session")
public class HomeBean extends BaseBean {
private static final String editUserBtn = "tab:form1:editUser";
private static final String deleteUserBtn = "tab:form1:deleteUser";
private static final String editCompBtn = "tab:form2:editComp";
private static final String deleteCompBtn = "tab:form2:deleteComp";
private static final String editAppBtn = "tab:form3:editApp";
private static final String deleteAppBtn = "tab:form3:deleteApp";
private List<User> users;
private List<Computer> computers;
private List<Application> applications;
private User selectedUser, newUser;
private Computer selectedComputer, newComputer;
private Application selectedApplication, newApplication;
private String deleteUserMsg, deleteCompMsg, deleteAppMsg;
private RequestContext rc;
@PostConstruct
public void init() {
setUsers(hibernateDBManager.getAllUsers());
setComputers(hibernateDBManager.getAllComputers());
setApplications(hibernateDBManager.getAllApplications());
newUser = new User();
newComputer = new Computer();
newApplication = new Application();
rc = RequestContext.getCurrentInstance();
}
public void addUser() throws NoSuchAlgorithmException {
if (hibernateDBManager.insertUser(newUser)) {
users.add(newUser);
newUser = new User();
updateUserButtons();
}
}
public void editUser() throws NoSuchAlgorithmException {
if (hibernateDBManager.updateUser(selectedUser)) {
users.set(users.indexOf(selectedUser), selectedUser);
selectedUser = null;
updateUserButtons();
}
}
public void deleteUser() throws IOException {
if (selectedUser != null) {
if (hibernateDBManager.deleteUserById(selectedUser.getUserId()) > 0) {
users.remove(selectedUser);
selectedUser = null;
updateUserButtons();
}
}
}
public void addComputer() {
if (newComputer != null && hibernateDBManager.insertComputer(newComputer)) {
computers.add(newComputer);
newComputer = new Computer();
updateCompButtons();
}
}
public void editComputer() {
if (hibernateDBManager.updateComputer(selectedComputer)) {
computers.set(computers.indexOf(selectedComputer), selectedComputer);
selectedComputer = null;
updateCompButtons();
}
}
public void deleteComputer() {
if (selectedComputer != null) {
if (hibernateDBManager.deleteComputerById(selectedComputer.getComputerId()) > 0) {
computers.remove(selectedComputer);
selectedComputer = null;
updateCompButtons();
}
}
}
public void addApplication() {
if (newApplication != null && hibernateDBManager.insertApplication(newApplication)) {
applications.add(newApplication);
newApplication = new Application();
updateAppButtons();
}
}
public void editApplication() {
if (hibernateDBManager.updateApplication(selectedApplication)) {
applications.set(applications.indexOf(selectedApplication), selectedApplication);
selectedApplication = null;
updateAppButtons();
}
}
public void deleteApplication() {
if (selectedApplication != null) {
if (hibernateDBManager.deleteApplicationById(selectedApplication.getAppId()) > 0) {
applications.remove(selectedApplication);
selectedApplication = null;
updateAppButtons();
}
}
}
public void onUserRowSelect(SelectEvent event) {
setSelectedUser((User) event.getObject());
setDeleteUserMsg("Are you sure you want to delete user "
+ selectedUser.getFirstName() + " " + selectedUser.getLastName() + "?");
}
public void onCompRowSelect(SelectEvent event) {
setSelectedComputer((Computer) event.getObject());
deleteCompMsg = "Are you sure you want to delete computer "
+ selectedComputer.getComputerName()
+ " (" + selectedComputer.getIpAddress() + ") ?";
}
public void onAppRowSelect(SelectEvent event) {
setSelectedApplication((Application) event.getObject());
deleteAppMsg = "Are you sure you want to delete application "
+ selectedApplication.getAppName() + "?";
}
protected void updateUserButtons() {
rc.update(editUserBtn);
rc.update(deleteUserBtn);
}
protected void updateCompButtons() {
rc.update(editCompBtn);
rc.update(deleteCompBtn);
}
protected void updateAppButtons() {
rc.update(editAppBtn);
rc.update(deleteAppBtn);
}
public String getDeleteUserMsg() {
return deleteUserMsg;
}
public void setDeleteUserMsg(String deleteUserMsg) {
this.deleteUserMsg = deleteUserMsg;
}
public String getDeleteCompMsg() {
return deleteCompMsg;
}
public void setDeleteCompMsg(String deleteCompMsg) {
this.deleteCompMsg = deleteCompMsg;
}
public String getDeleteAppMsg() {
return deleteAppMsg;
}
public void setDeleteAppMsg(String deleteAppMsg) {
this.deleteAppMsg = deleteAppMsg;
}
//Other getters/setters
}
Что мне нужно сделать - это сделать selectBoolean/selectOneMenu или что-то simmilar, который позволяет выбрать только из 2 вариантов (true/false). Как на таблице пользователей (роль поля), которая устанавливается на роль текущего selectedUser в:
Если я заменяю
<p:selectOneMenu id="appLicense2" required="true" style="width: 80px;" value="#{homeBean.selectedApplication.licenseRequired}" >
<f:selectItem itemLabel="true" itemValue="#{true}" />
<f:selectItem itemLabel="false" itemValue="#{false}" />
</p:selectOneMenu>
с простой
<p:inputText id="appLicense2" value="#{homeBean.selectedApplication.licenseRequired}"/>
тогда все работает ОК, и у меня есть правильные значения. Но это не подходит, потому что мне нужно выбирать только из двух допустимых значений, а не вводить случайный текст.
Любые идеи, как решить эту проблему? Каждый ответ высоко оценен!
спасибо.