[英]JSF + Primefaces: Ajax CRUD-Actions in Master-Detail-View only work once per page-load
I'm using Mojarra 2.0.3 on JBoss AS 6 with Primefaces 2.2.1 + Hibernate. 我在带有Primefaces 2.2.1 + Hibernate的JBoss AS 6上使用Mojarra 2.0.3。
I've got a master-detail-view with p:datatable and p:dialog for Person (prename, lastname). 我有一个p-datatable和p:dialog为Person(姓氏,姓氏)的主从视图。
Code of Person.java: Person.java代码:
@Entity
public class Person implements Serializable {
private static final long serialVersionUID = 279906432340876832L;
@Id
@GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
private Long id;
private String prename;
private String lastname;
// getter and setter...
}
With a "create"-button a new instance can be created, with the "edit"-button, a selected item can be edited. 使用“创建”按钮可以创建新实例,使用“编辑”按钮可以编辑所选项目。
Code of .xhtml: .xhtml的代码:
<h:form id="personForm">
<!-- 2 Buttons to open create/edit Dialog -->
<p:panel id="tableButtons">
<p:commandButton value="create" action="#{personBean.showCreateView}"
update="personForm:detailPanel" oncomplete="personDialog.show()" />
<p:commandButton value="edit" action="#{personBean.showEditView}"
update="personForm:detailPanel" oncomplete="personDialog.show()"
rendered="#{personBean.rowSelected}" />
</p:panel>
<!-- DataTable for list-View -->
<p:dataTable var="item" styleClass="table"
value="#{personBean.personList}" id="personTable" paginator="true"
selectionMode="single" selection="#{personBean.selectedPerson}"
rowSelectListener="#{personBean.select}"
onRowSelectUpdate="personForm:tableButtons"
rowUnselectListener="#{personBean.unselect}"
onRowUnselectUpdate="personForm:tableButtons" rows="10">
<p:column sortBy="#{item.prename}">
<f:facet name="header">
<h:outputText value="prename" />
</f:facet>
<h:outputText value="#{item.prename}" />
</p:column>
<p:column sortBy="#{item.lastname}">
<f:facet name="header">
<h:outputText value="lastname" />
</f:facet>
<h:outputText value="#{item.lastname}" />
</p:column>
</p:dataTable>
<!-- Dialog for detailed-View -->
<p:dialog id="personDialog" widgetVar="personDialog">
<p:panel id="detailPanel">
<h:panelGrid cellpadding="4">
<h:outputText value="prename: " />
<h:inputText value="#{personBean.selectedPerson.prename}" />
<h:outputText value="lastname: " />
<h:inputText value="#{personBean.selectedPerson.lastname}" />
</h:panelGrid>
<p:commandButton value="persist"
actionListener="#{personBean.persist}"
rendered="#{personBean.createView}" update="personForm"
oncomplete="personDialog.hide()" />
<p:commandButton value="save" actionListener="#{personBean.merge}"
update="personForm" rendered="#{personBean.editView}"
oncomplete="personDialog.hide()" />
</p:panel>
</p:dialog>
</h:form>
The managedBean holds 2 boolean attributes createView/editView which appear in the render-attribute of the dialogs commandbuttons, a List for the DataTable, "selectedPerson" for Detail-View and another boolean to trigger edit-Button in case of row-selection in the DataTable. ManagedBean拥有2个布尔属性createView / editView,它们出现在对话框命令按钮的渲染属性中,DataTable的列表,Detail-View的“ selectedPerson”列表,以及另一个在选择行时触发edit-Button的布尔值。数据表。
Code of Managed-Bean: 托管Bean代码:
@ManagedBean(name = "personBean")
@ViewScoped
public class PersonMBean {
private List<Person> personList;
private Person selectedPerson;
// row in the table has been selected
private boolean rowSelected;
// only render the active View
private boolean createView;
private boolean editView;
// ... displayView and more possible
@EJB
private CRUDService crudService;
public PersonMBean() {
personList = new ArrayList<Person>();
selectedPerson = new Person();
}
// CRUD-options
public String persist(ActionEvent actionEvent) {
crudService.persist(selectedPerson);
return null;
}
public String merge(ActionEvent actionEvent) {
selectedPerson = crudService.merge(selectedPerson);
return null;
}
// switch between Views
public String showCreateView() {
selectedPerson = new Person();
createView = true;
editView = false;
return null;
}
public String showEditView() {
createView = false;
editView = true;
return null;
}
public List<Person> getPersonList() {
return crudService.getAllPerson();
}
public Person getSelectedPerson() {
if (selectedPerson == null) {
selectedPerson = new Person();
}
return selectedPerson;
}
public String select(SelectEvent event) {
setRowSelected(true);
return null;
}
public String unselect(UnselectEvent event) {
setRowSelected(false);
return null;
}
// getter + setter
public void setPersonList(List<Person> personList) {this.personList = personList;}
public void setSelectedPerson(Person selectedPerson) {this.selectedPerson = selectedPerson;}
public boolean isRowSelected() {return rowSelected;}
public void setRowSelected(boolean rowSelected) {this.rowSelected = rowSelected;}
public void setCreateView(boolean createView) {this.createView = createView;}
public boolean isCreateView() {return createView;}
public void setEditView(boolean editView) {this.editView = editView;}
public boolean isEditView() {return editView;}
}
The problem is that while a single create/edit Person is successfull, after that a create-Action inserts an empty row and an edit-Action inserts a row with wrong values. 问题是,虽然单个创建/编辑人员成功,但是之后,创建动作将插入空行,而编辑动作将插入具有错误值的行。 When I reload the page, again the first action is ok, the second one fails... :(
当我重新加载页面时,再次执行第一个操作就可以了,第二个操作失败了... :(
I suppose that the PersonMBean.selectedPerson has got an obsolete state but I can not figure it out nor can I find a solution to solve it. 我想PersonMBean.selectedPerson的状态已经过时,但是我无法弄清楚,也找不到解决方案。
ps crudService just calls em.persist + em.merge ps crudService只是调用em.persist + em.merge
Code of CRUDService: CRUDService的代码:
@Stateless
public class CRUDService {
@PersistenceContext
EntityManager em;
public <T> T persist(T t) {
this.em.persist(t);
return t;
}
public <T> T merge(T t) {
return this.em.merge(t);
}
@SuppressWarnings("unchecked")
public List<Person> getAllPerson() {
Query q = em.createQuery("from Person");
return q.getResultList();
}
}
The web.xml looks like this: web.xml看起来像这样:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID"
version="3.0">
<context-param>
<param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
<param-value>false</param-value>
</context-param>
<servlet>
<servlet-name>facesServlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
</web-app>
I'm really struggling on this one, hope you can help me. 我真的很努力,希望您能帮助我。
If anything is wrong with formatting / style please let me know so I can update it. 如果格式/样式有任何问题,请告诉我,以便我进行更新。
查看http://www.jaxio.com/cn/celerio.html,它输出JSF + Primefaces主页面/详细页面,可以用作示例
Can you add this to your web.xml then rerun your code ? 您可以将其添加到web.xml中,然后重新运行代码吗?
<context-param>
<param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
<param-value>false</param-value>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.