Olá Pessoal,
Estou desenvolvendo um formulário de cadastro de menu, ao cadastrar um novo item está funcionando normalmente, minha dúvida está no momento de fazer o update.
Quando seleciono o registro o qual quero alterar, os inputs são preenchidos normalmente, quando executo a ação salvar no managed-bean o id do objeto está nulo, ou seja, o objeto é enviado com todos os atributos menos o Id, e por esse motivo é inserido um novo registro e não é feito a atualização do mesmo.
Obs.: meu form não contem contem nenhum input ou hidden referenciando o id do objeto.
Quando utilizo o campo hidden para referenciar o id do objeto, ao tentar persistir o objeto utilizando o metodo saveOrUpdate hibernate, é lançada uma exception informando que existe outro objeto persistido na sessão com o mesmo id. A solução paleativa foi utilizar o merge(), mas acredito que tem outra forma de resolver isso, pois o objeto deveria ter sido envidado completo com o mesmo id e o mesmo objeto da sessão, correto?
A pegunta é a seguinte:
É possível enviar o objeto selecionado sem precisar do campo hidden referenciando o id, pois jsf utiliza o objeto e não o apenas o valor do objeto, estou correto?
O que devo fazer?
O managed-bean está com escope request, percebi que se utilizar o scope session o update funciona normalmente, mas utilizar sessão para isso não é recomendado…
<ui:define name="principal">
<h:form>
<h:panelGrid columns="3">
<h:outputLabel value="Nome" for="nome" />
<h:inputText value="#{MenuMB.menu.nome}" id="nome" maxlength="255" size="50" label="Nome" required="true"/>
<h:message for="nome" styleClass="erroMsg"/>
<h:outputLabel value="Menu Superior" for="menusup" />
<h:selectOneMenu id="menusup" value="#{MenuMB.menu.menuSuperior}">
<f:selectItems value="#{MenuMB.menuSuperior}"/>
</h:selectOneMenu>
<h:message for="menusup" styleClass="erroMsg"/>
<h:outputLabel value="Tipo Menu" for="tipomenu" />
<h:selectOneRadio id="tipomenu" value="#{MenuMB.menu.tipoMenu}" label="Tipo Menu" required="true">
<f:selectItems value="#{MenuMB.tipoMenu}"/>
</h:selectOneRadio>
<h:message for="tipomenu" styleClass="erroMsg"/>
<h:outputLabel value="Local / Navegação" for="nav" />
<h:inputText value="#{MenuMB.menu.navegacao}" id="nav" maxlength="255" size="50" label="Navegação" required="true"/>
<h:message for="nav" styleClass="erroMsg"/>
<h:outputLabel value="Ordem" for="ordem"/>
<h:inputText value="#{MenuMB.menu.ordem}" id="ordem" maxlength="2" size="2" label="Ordem" converter="javax.faces.Integer">
</h:inputText>
<h:message for="ordem" styleClass="erroMsg"/>
</h:panelGrid>
<h:commandButton value="Salvar" action="#{MenuMB.save}"/>
No mesmo formulario realizei um teste com o dataTable, codigo abaixo:
<h:dataTable var="menu2" value="#{MenuMB.listMenu}">
<f:facet name="Nome" />
<h:column>
<h:commandLink value="#{menu2.nome}" action="#{MenuMB.selectMenu}" immediate="true"/>
</h:column>
</h:dataTable>
E montei um laço e uma lista, utilizei o commanLink juntamente com o <f:setPropertyActionListener> para selecionar o registro:
<ui:repeat var="menu" value="#{MenuMB.listMenu}">
<h:outputText value="#{menu.nome}"/>
<h:panelGrid columns="3" width="100%" border="1">
<h:commandLink value="Alterar" action="#{MenuMB.selectMenu}" immediate="true">
<f:setPropertyActionListener value="#{menu}" target="#{MenuMB.menu}"></f:setPropertyActionListener>
</h:commandLink>
</h:panelGrid>
</ui:repeat>
Obrigado!!!