Conversational bean range for the same look

I have a DTO that has a list. I want to add new rows to datatable when user clicks add button. But when I click add , the dto ie constructor is called and the value is initialized, and the list size is 0. bean is the conversation area. Do I have to start and end a conversation for the same view when using the bean conversation area? I use the same bean for editing and it works well. How to solve the initialization problem when using richfaces 4 and jsf 2 and ajax.

View:

<rich:panel id ="dataPnl"> <rich:dataTable value="#{legendbean.legendDTO.list}" var="legend" style="width:100%"> <rich:column> <f:facet name="header"> <h:outputText value="SN"/> </f:facet> <h:inputText value="#{legend.sn}"/> </rich:column> <rich:column> <f:facet name="header"> <h:outputText value="Description"/> </f:facet> <h:inputText value="#{legend.desc}"/> </rich:column> <rich:column> <a4j:commandLink value="Add" actionListener="#{legendbean.addLegendRange()}" render="nisForm:dataPnl"/> <h:outputText value=" / "/> <a4j:commandLink value="Remove" actionListener="#{legendbean.removeLegendRange(legend)}" render="nisForm:dataPnl"/> </rich:column> </rich:dataTable> </rich:panel> 

Bean:

 @Named("legendbean") @ConversationScoped public class LegendController implements Serializable { LegendDTO legendDTO = new LegendDTO(); String selectedLegend; boolean edit; @Inject private Conversation conversation; public boolean isEdit() { return edit; } public void setEdit(boolean edit) { this.edit = edit; } public LegendController() { Logger.getLogger(LegendController.class.getName()).warning("The value of Edit is : " + edit); if (!edit) { legendDTO.getList().add(new Legend()); Logger.getLogger(LegendController.class.getName()).warning("The size of list" + legendDTO.getList().size()); } } public LegendDTO getLegendDTO() { return legendDTO; } public void setLegendDTO(LegendDTO legendDTO) { this.legendDTO = legendDTO; } public void addLegendRange() { Logger.getLogger(LegendController.class.getName()).warning("List Size " + legendDTO.getList().size()); legendDTO.getList().add(new Legend()); Logger.getLogger(LegendController.class.getName()).warning("List Size " + legendDTO.getList().size()); } public void removeLegendRange(Legend legend) { if (legendDTO.getList().size() != 1) { legendDTO.getList().remove(legend); } } public String saveLegend() { Logger.getLogger(LegendController.class.getName()).warning("Save Legend Edit" + edit); LegendDAO dao = new LegendDAO(); if (dao.addLegend(legendDTO, edit)) { if (edit) { conversation.end(); edit = false; Logger.getLogger(LegendController.class.getName()).warning("Save Legend Edit" + edit); return "VIEWLEGEND"; } else { legendDTO = new LegendDTO(); legendDTO.getList().add(new Legend()); FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Saved !")); return ""; } } else { FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Could Not Save Confim if you have already defined Legend " + legendDTO.getLegendName() + "!")); return ""; } } public List<LegendDTO> getLegends() { LegendDAO dao = new LegendDAO(); return dao.getLegendDTO(); } //All function from here are for legend delete public void deleteLegendType(LegendDTO dto) { LegendDAO dao = new LegendDAO(); if (dao.deleteLegendType(dto.getLegendName())) { FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Deleted !")); } else { FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Deleted Error !")); } } //All function from here is to legend edit public String editLegendType(LegendDTO dto) { conversation.begin(); edit = true; legendDTO = dto; LegendDAO dao = new LegendDAO(); dto.getList().clear(); try { List<Legend> legends = dao.getDetailForEditLegend(dto.getLegendName()); dto.setList(legends); } catch (SQLException ex) { Logger.getLogger(LegendController.class.getName()).warning("SQL EXception has occoured"); } Logger.getLogger(LegendController.class.getName()).warning("The size of list" + dto.getList().size()); return "addLegend"; } public String cancel() { conversation.end(); return "VIEWLEGEND"; } } 
+4
source share
2 answers

Yes, you need to start a lengthy conversation to make your conversation (and the beans scope) cover several requests, otherwise the conversation will be killed at the end of the JSF request (the conversation ends by default: see ConversationScoped javadoc ).

Also, the general solution in cases like yours is to use ViewScoped beans, but the annotation is specific to JSF2 and not presented in CDI (you can transfer it to CDI or use the loop module, more information: http: // www. verborgh.be/articles/2010/01/06/porting-the-viewscoped-jsf-annotation-to-cdi/ ).

+2
source

If you are not limited to using CDI / Seam annotations, you can change the bean to use @ManagedBean(name="legendbean") in the javax.faces.bean.ManagedBean package, and then use the @ViewScoped annotation for your class, which ensures that for a long time since the user is on the same page, you will use the same instance of the managed bean. Nothing else should change at all with your installation, all @Inject will work as usual. To initialize the legendDTO.list , annotate the method in your ViewScoped JSF bean with the @PostConstruct JSF annotation and place the list logic there. You can safely add / remove to the list without reinitializing to empty. But you must remember to make changes to this list in the database.

Just think, you can show a popup that allows your users to confirm that they want to remove anything from your db, as a safe practice. Greetings

+2
source

Source: https://habr.com/ru/post/1432046/


All Articles