Como exibir um registro em uma dataTable após salvá-lo no Banco de Dados?

5 respostas
ajaxjsfprimefacesjava
J

Oi pessoal.

Tenho duas tabelas no SQL Server relacionadas conforme abaixo:

imagem das tabelas Demanda e Anotacoes

Conforme abaixo, no meu ListDemandas.jsf há uma datatable onde o usuário pode inserir registros que são gravados na tabela Demandas, o que funciona normalmente.

<h:form id="DemandasListForm">

<p:panel id="PanelListForm" header="#{adeBundle.ListDemandasTitle}">

    <p:commandButton id="createButton"         value="Create Demanda"  update=":DemandasCreateForm" oncomplete="PF('DemandasCreateDialog').show()" actionListener="#{demandasController.prepareCreate}" />
    <p:commandButton id="createAnotacaoButton" value="Create Anotacao" update=":AnotacaoCreateForm, datalist" oncomplete="PF('AnotacaoCreateDialog').show()" />

    <p:dataTable id="datalist"
                 value="#{demandasController.items}"
                 lazy="false"
                 rowKey="#{item.id}"
                 var="item"
                 selection="#{demandasController.selected}"
                 widgetVar="demandasTable">

        <p:ajax event="rowSelect"   update="@form:createAnotacaoButton, @form:createButton" listener="#{demandasController.resetParents}"/>
        <p:ajax event="rowUnselect" update="@form:createAnotacaoButton, @form:createButton" listener="#{demandasController.resetParents}"/>
        <p:ajax event="contextMenu" update="@form:createAnotacaoButton, @form:createButton" listener="#{demandasController.resetParents}"/>

        <p:column id="idCod" >
            <f:facet name="header">
                <h:outputText value="id"/>
            </f:facet>
            <h:outputText value="#{item.id}"/>
        </p:column>

        <!-- some columns ommited -->    

        <p:rowExpansion>
            <p:panelGrid>
                <p:column>
                    <p:row>
                        <p:accordionPanel value="Mais informacoes da Demanda" multiple="true">
                            <p:tab title="Anotacoes}" >
                                <p:dataList value="#{item.anotacoesCollection}" var="anotacoesCollectionItem" itemType="none" emptyMessage="-" >
                                    <h:outputText value="#{anotacoesCollectionItem.anotacao.toString()}" />
                                </p:dataList>
                            </p:tab>
                        </p:accordionPanel>
                    </p:row>
                </p:column>
            </p:panelGrid>
        </p:rowExpansion>
    </p:dataTable>
</p:panel>
<ui:include src="/WEB-INF/include/confirmation.xhtml"/>    
</h:form>

Ele também pode clicar num botão Criar Anotação (id=createAnotacaoButton acima), o qual invoca um Dialog (id=AnotacaoCreateDlg abaixo), onde nele poderá inserir dados que serão salvos na tabela Anotacao.

Após ele clicar no botão para salvar a Anotacao, o Dialog é ocultado e o registro é criado com sucesso na tabela Anotacao. Isso está funcionando ok já.

<p:dialog id="AnotacaoCreateDlg" widgetVar="AnotacaoCreateDialog" modal="true" appendTo="@(body)" header="Create Anotacoes" >

<h:form id="AnotacaoCreateForm" >

    <h:panelGroup id="display" >
        <p:panelGrid columns="2" columnClasses="column">

            <p:outputLabel value="CreateAnotacoesLabel_anotacao" for="anotacao" />
            <h:panelGroup>
                <p:inputTextarea id="anotacao" value="#{anotacoesController.selected.anotacao}" title="CreateAnotacoesTitle_anotacao" />
            </h:panelGroup>

            <p:outputLabel value="CreateAnotacoesLabel_date" for="date" />
            <h:panelGroup>
                <p:calendar id="date" value="#{demandasController.currentDate}" title="CreateAnotacoesTitle_date" />
            </h:panelGroup>

    <!-- some other input fields ommited -->                

        </p:panelGrid>
    </h:panelGroup>

    <p:commandButton actionListener="#{anotacoesController.saveNew}" value="Save" update="display, :DemandasListForm:datalist, :growl" oncomplete="handleSubmit(xhr,status,args,PF('AnotacaoCreateDialog'));" >
        <p:confirm header="Confirmation" message="Are you sure ?" />
    </p:commandButton>

    <p:commandButton value="Cancel" oncomplete="PF('AnotacaoCreateDialog').hide()" update="display" process="@this" immediate="true" resetValues="true"/>

</h:form>
</p:dialog>

O problema é que essa Anotacao que foi criada não está sendo exibida na tabela Demanda; essa Anotacao será exibida apenas depois que eu reiniciar o servidor web ou fazer redeploy da aplicação.

Alguém sabe como eu faço para exibir uma Anotacao recém-criada na datatable de Demandas logo após eu tê-la criado, sem que para isso, eu tenha que reiniciar o servidor ou fazer redeploy ?

Abaixo, classe java relacionada com a ação para slavar no Banco de Dados:

public abstract class AbstractController<T> implements Serializable {

private static final long serialVersionUID = 1L;

private Class<T> itemClass;
private T selected;
private Collection<T> items;
private List<T> filteredItems;

private enum PersistAction {

    CREATE,
    DELETE,
    UPDATE
}

public AbstractController() {
}

public AbstractController(Class<T> itemClass) {
    this.itemClass = itemClass;
}

public void setSelected(T selected) {
    if (selected != null) {
        if (this.selected == null || !this.selected.equals(selected)) {
            this.selected = this.ejbFacade.findWithParents(selected);
            this.setChildrenEmptyFlags();
        }
    } else {
        this.selected = null;
    }
}

protected void setEmbeddableKeys() {
}

protected void initializeEmbeddableKey() {
}

public Collection<T> getItems() {
    if (itemClass.getSimpleName().equals("Demandas")) {
        if (sessionPrefixo == 9600) {
            items = this.ejbFacade.findAll();
        } else {
            items = this.ejbFacade.findAllVenceHojeByNomeUorPos(uorPosDiageJurisdiciona);
        }
    }
    return items;
}

public void save(ActionEvent event) {
    String msg = ResourceBundle.getBundle("/adeBundle").getString(itemClass.getSimpleName() + "Updated");
    persist(PersistAction.UPDATE, msg);

    if (!isValidationFailed()) {
        // Update the existing entity inside the item list
        List<T> itemList = refreshItem(this.selected, this.items);

        // If the original list has changed (it is a new object)
        if (this.items != itemList) {
            this.setItems(itemList);
        }
        // Also refresh the filteredItems list in case the user has filtered the DataTable
        if (filteredItems != null) {
            refreshItem(this.selected, this.filteredItems);
        }
    }
}

public void saveNew(ActionEvent event) {
    String msg = ResourceBundle.getBundle("/adeBundle").getString(itemClass.getSimpleName() + "Created");
    persist(PersistAction.CREATE, msg);

    if (!isValidationFailed()) {
        items = null; // Invalidate list of items to trigger re-query.
        lazyItems = null; // Invalidate list of lazy items to trigger re-query.
    }
}

private void persist(PersistAction persistAction, String successMessage) {
    if (selected != null) {
        this.setEmbeddableKeys();
        try {
            if (persistAction != PersistAction.DELETE) {
                this.ejbFacade.edit(selected);
            } else {
                this.ejbFacade.remove(selected);
            }
            this.setChildrenEmptyFlags();
            JsfUtil.addSuccessMessage(successMessage);
        } catch (EJBException ex) {
            Throwable cause = JsfUtil.getRootCause(ex.getCause());
            if (cause != null) {
                if (cause instanceof ConstraintViolationException) {
                    ConstraintViolationException excp = (ConstraintViolationException) cause;
                    for (ConstraintViolation s : excp.getConstraintViolations()) {
                        JsfUtil.addErrorMessage(s.getMessage());
                    }
                } else {
                    String msg = cause.getLocalizedMessage();
                    if (msg.length() > 0) {
                        JsfUtil.addErrorMessage(msg);
                    } else {
                        JsfUtil.addErrorMessage(ex, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
                    }
                }
            }
        } catch (Exception ex) {
            Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
            JsfUtil.addErrorMessage(ex, ResourceBundle.getBundle("/adeBundle").getString("PersistenceErrorOccured"));
        }
    }
}

public T prepareCreate(ActionEvent event) {
    T newItem;
    try {
        newItem = itemClass.newInstance();
        this.selected = newItem;
        initializeEmbeddableKey();
        return newItem;
    } catch (InstantiationException | IllegalAccessException ex) {
        Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
    }
    return null;
}

public boolean isValidationFailed() {
    return JsfUtil.isValidationFailed();
}

public String getComponentMessages(String clientComponent, String defaultMessage) {
    return JsfUtil.getComponentMessages(clientComponent, defaultMessage);
}

@PostConstruct
public void initParams() {
    Object paramItems = FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get(itemClass.getSimpleName() + "_items");
    if (paramItems != null) {
        setItems((Collection<T>) paramItems);
    }
}

private List<T> refreshItem(T item, Collection<T> items) {

    List<T> itemList;
    if (this.items instanceof List) {
        itemList = (List<T>) items;
    } else {
        itemList = new ArrayList<>(items);
    }
    int i = itemList.indexOf(item);
    if (i >= 0) {
        try {
            itemList.set(i, item);
        } catch (UnsupportedOperationException ex) {
            return refreshItem(item, new ArrayList<>(items));
        }
    }
    return itemList;
}

public AbstractFacade<T> getEjbFacade() {
    return ejbFacade;
}

public void setEjbFacade(AbstractFacade<T> ejbFacade) {
    this.ejbFacade = ejbFacade;
}
}

Agradeço muito pela atenção.

5 Respostas

M

Olá @jMarcel

Você esta usando JPA? Se sim, qual implementação?

Já tentou desativar o cache?

J

Olá @Mike !

Estou usando JPA 2. (Eclipselink).

Sobre o cache, não tenho certeza.
Como eu faço para para desativar o cache?

Valeu!

M

Tenta isso no persistence.xml

<property name="eclipselink.query-results-cache" value="false"/>
<property name="eclipselink.cache.shared.default" value="false"/>
J

Oi @Mike !

Eu alterei no persistence.xml, encontrei a property eclipselink.cache.shared.default e a defini como false; já a property eclipselink.query-results-cache, eu não encontrei nas opções disponíveis para definir diretamente no persistence.xml, a qual acredito que faria isso para todas as enties, mas busquei nesse link e incluí na query da entity class em questão o seguinte:

@NamedQueries({
@NamedQuery(name = "Anotacoes.findAll", query = "SELECT a FROM Anotacoes a",
hints = {
            @QueryHint(name = "eclipselink.query-results-cache", value = "false")
        })
,

Mas mesmo assim continua não aparecendo a Anotação da tabela das Demandas.

Cara, o que será que pode ser? Alguma outra ideia ?

M

Você tentou isso ja?

Query query = this.entityManager.createQuery(selectQuery);
query.setParameter(param, value);

query.setHint(QueryHints.REFRESH, HintValues.TRUE);

entityList = readQuery.getResultList();
@Entity
@Cacheable(false)
public class SomeEntity {
    // ...
}

Ou então entityManager.clear() no final do método de persistencia

Criado 27 de setembro de 2018
Ultima resposta 19 de out. de 2018
Respostas 5
Participantes 2