如何解决Primefaces:<p:dataTable>的数据源更改或并发操作将导致不一致的参数从jsf-el传递到支持bean
如果我有一个由requestScoped命名bean控制的dataTable,则命名bean(后备bean)从EJB查询数据,并通过EntityManager和JPA查询EJB查询数据。
对于视图部分,我使用PrimeFaces中的dataTable: 我的问题是:如果我在一个或两个浏览器中打开两个选项卡(问题相同):我在一个选项卡中删除了一行,然后转到未刷新的另一选项卡(因此删除的行仍然存在)。如果我再次按delete commandLink,则删除行当然会被删除,因为页面已刷新,但问题是它也删除了它下面的行。 顺便说一下,我的JSF版本是2.2,素数是4.0(现在我将其替换为8.0,错误仍然存在)。 是jsf还是primefaces错误(我从未尝试过h:commandLink和h:dataTable)还是我犯了一些错误?
You can reference below code for named bean:
@Named(value="allIndustryController")
@RequestScoped
public class AllIndustryController {
@Inject
IndustryTypeBean industryTypeBean;
private List<Industry> industries;
public AllIndustryController() {
}
@PostConstruct
public void init() {
industries = industryTypeBean.getAllIndustrys();
}
public List<Industry> getIndustries() {
return industries;
}
public void setIndustries(List<Industry> industries) {
this.industries = industries;
}
public String deleteIndustry(int industryID) {
try {
boolean result = industryTypeBean.removeIndustry(industryID);
if (result) {
init();
FacesContext.getCurrentInstance().addMessage(null,new FacesMessage("Industry " + industryID +" has been deleted succesfully"));
}
}catch(Exception ex){
FacesContext.getCurrentInstance().addMessage(null,new FacesMessage("Delete Industry Failed"));
}
return "allIndustries.xhtml?faces-redirect=true";
}
public void updateIndustry(int industryID,String industryName) {
Industry industry = industryTypeBean.findIndustryByID(industryID);
industry.setIndustryName(industryName);
industryTypeBean.editIndustry(industry);
}
public String addIndustry() {
Industry industry = new Industry();
industryTypeBean.addIndustry(industry);
return "allIndustries.xhtml?faces-redirect=true";
}
}
dataTable的代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>All Industries</title>
<h:outputStylesheet library="css" name="bootstrap.min.css"></h:outputStylesheet>
</h:head>
<body>
<div class="navbar navbar-expand-lg navbar-light bg-light">
<div class="navbar-brand">Customer Management System</div>
<div class="collapse navbar-collapse">
<ul class="navbar-nav mr-auto">
<li class="nav-item active"><h:link class="nav-link"
value="Home | " outcome="index.xhtml" /></li>
<li class="nav-item"><h:link class="nav-link"
value="Manage All Users | " outcome="allUsers.xhtml" /></li>
<li class="nav-item"><h:link class="nav-link"
value="Manage All Customers |" outcome="allCustomers.xhtml" /></li>
<li class="nav-item"><h:link class="nav-link"
value="Manage Industries |" outcome="allIndustries.xhtml" /></li>
<h:form>
<li class="nav-item"><h:commandLink class="nav-link"
value="Log out" action="#{loginController.logout()}" /></li>
</h:form>
</ul>
</div>
</div>
<h:form id="MyForm">
<p:dataTable class="table table-bordered table-striped"
id="myIndustryList" value="#{allIndustryController.industries}"
var="industry">
<p:column headerText="industryID">
<p:outputLabel value="#{industry.industryID}" id="industryID" />
</p:column>
<p:column headerText="industryName">
<p:inputText value="#{industry.industryName}" id="industryName" />
</p:column>
<p:column headerText="Operations">
<p:commandLink value="Delete | " ajax="true"
action="#{allIndustryController.deleteIndustry(industry.industryID)}"
disabled="#{industry.industryID == null}" update="myIndustryList">
<p:confirm header="Confirmation" message="Are you sure?"
icon="pi pi-exclamation-triangle" />
</p:commandLink>
<p:commandButton value="update Name"
action="#{allIndustryController.updateIndustry(industry.industryID,industry.industryName)}"
oncomplete="PF('cd').show()">
<!-- <f:param name="userAccount" value="#{normalUser.account}" /> -->
</p:commandButton>
</p:column>
<!-- <h:link value="View | " outcome="userDetail.xhtml">
pass the parameter to next page,the param name is propertyID,and the value is index + 1.
You can get the value from next page using the indexController
<f:param name="userAccount" value="#{normalUser.account}" />
</h:link>
<h:link value="Edit | " outcome="editUser.xhtml">
pass the parameter to next page,and the value is index + 1.
You can get the value from next page using the indexController
<f:param name="userAccount" value="#{normalUser.account}" />
</h:link> -->
<!-- reference:https://stackoverflow.com/questions/19362983/how-to-add-confirmation-dialog ; https://www.primefaces.org/showcase/ui/data/datatable/basic.xhtml-->
</p:dataTable>
<p:confirmDialog global="true" showEffect="fade" hideEffect="fade">
<p:commandButton value="Yes" type="button"
styleClass="ui-confirmdialog-yes" icon="pi pi-check" />
<p:commandButton value="No" type="button"
styleClass="ui-confirmdialog-no" icon="pi pi-times" />
</p:confirmDialog>
<h:outputText value=" " />
<p:dialog header="Save the name" severity="alert" widgetVar="cd">
<h:outputText value="The Industry Name is saved" />
</p:dialog>
<div>
<h:commandButton id="add" value="Add"
action="#{allIndustryController.addIndustry()}"
class="btn btn-primary" />
<h:commandButton id="viewAll" value="View All"
action="allIndustries.xhtml?faces-redirect=true"
class="btn btn-primary">
</h:commandButton>
</div>
<!-- <div>
<h:inputText value="#{adminApplication.searchedAccount}"
id="searchByAccount"
onchange="if (document.getElementById('MyForm:searchByAccount').value.trim() == '') {document.getElementById('MyForm:searchByAccount').value = '';} " />
<h:commandButton id="search" value="Search by Account"
action="#{adminApplication.searchUserByAccount(adminApplication.searchedAccount)}"
class="btn btn-primary">
</h:commandButton>
</div> -->
</h:form>
</body>
</html>
----------------------------------更新---------------- ---------------
实际上,我通过使用
我想我可以将问题总结如下: 每当我在支持bean中更新实际dataTable的数据源时,我都无法在支持bean的方法中传递参数(参数将不一致,这似乎是索引问题?只是一个疯狂的猜测)。无论如何,f:param总是可以给出正确的答案
对于更多感兴趣的人,我发布了IndustryType.java代码,尽管它与问题无关。问题仍然在于素数如何处理xhtml文件。欢迎获得更详细的解释,并希望这篇文章对更多人有用:
package beans;
import java.io.Serializable;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import entity.Industry;
import repository.IndustryRepository;
@Named
@SessionScoped
public class IndustryTypeBean implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@EJB
IndustryRepository industryRepository;
public List<Industry> getAllIndustrys(){
try {
List<Industry> industrys = industryRepository.getAllIndustries();
return industrys;
}catch (Exception ex) {
Logger.getLogger(IndustryTypeBean.class.getName()).log(Level.SEVERE,null,ex);
}
return null;
}
public boolean addIndustry(Industry Industry) {
try {
industryRepository.addIndustry(Industry);
return true;
}catch(Exception ex) {
Logger.getLogger(IndustryTypeBean.class.getName()).log(Level.SEVERE,ex);
}
return false;
}
public boolean removeIndustry(int industryID) {
try {
industryRepository.deleteIndustry(industryID);
return true;
} catch(Exception ex) {
Logger.getLogger(IndustryTypeBean.class.getName()).log(Level.SEVERE,ex);
}
return false;
}
public boolean editIndustry(Industry Industry) {
try {
industryRepository.updateIndustry(Industry);
return true;
}catch(Exception ex) {
Logger.getLogger(IndustryTypeBean.class.getName()).log(Level.SEVERE,ex);
}
return false;
}
public Industry findIndustryByID (int industryID) {
try {
return industryRepository.findIndustryByID(industryID);
}catch(Exception ex) {
Logger.getLogger(IndustryTypeBean.class.getName()).log(Level.SEVERE,ex);
}
return null;
}
}
在JSF中,viewscope和flowscope有CDI,因此您必须使用其他实现。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。