2
Hello, I have an object that is managed by Hibernate. On screen, an attribute of this object is updated the value and Hibernate immediately triggers an update in the database, without even going through methods in the controller or the data persistence layer.
Can someone help me with that?
<!--MODAL BAIXA DE LANCAMENTO-->
<div id="modal_baixa_lancamento" class="modal modal-fixed-footer col-xs-12 col-md-10"
style="height: 620px;max-height: 100%;">
<h:form prependId="false" id="form_modal_cad_despesa_imediata">
<h:panelGroup id="body_modal_baixa_lancamento" layout="block" styleClass="modal-content">
<h2 class="label-title" style="text-align: center">
<i class="icon-checkmark-circle"> </i> Pagamento de Despesa
</h2>
<div class="divider col-xs-12"></div>
<div class="row no-margin">
<!--Detalhes-->
<div class="row">
<!--Detalhes-->
<div class="col-xs-12 m-b-15">
<h2 class="label-title no-margin">
<i class="icon-info-circle"> </i> Detalhes
</h2>
</div>
<!--Fornecedor-->
<div class="col-xs-12 col-sm-12 col-md-6 form-group">
<label>
Fornecedor
</label>
<h:panelGroup id="fornecedoresFiltro" styleClass="form-group" layout="block">
<div class="col-xs-12 col-sm-12" style="padding-left: 0px; ">
<div class="fg-line">
<h:inputText id="nomeFornecedor" pt:placeholder="Nome"
styleClass="form-control" disabled="true"
value="#{listaContaPagar.contaAPagar.favorecido.nome}"/>
</div>
</div>
</h:panelGroup>
</div>
<!--Descrição-->
<div class="col-xs-12 col-sm-12 col-md-6 form-group">
<label for="descricao">
<span style="color: red">*</span> Descrição
</label>
<div class="fg-line">
<h:inputText id="descricao" pt:placeholder="Digite a descrição"
styleClass="form-control" required="true" process="@this"
requiredMessage="Informe uma Descrição" event="change"
disabled="true"
value="#{listaContaPagar.contaAPagar.descricao}">
</h:inputText>
</div>
</div>
<!--Data de Vencimento-->
<div class="col-xs-12 col-sm-6 col-md-3 form-group">
<label for="dataVencimento">
<span style="color: red">*</span> Data de Vencimento
</label>
<div class="fg-line">
<h:inputText id="dataVencimento"
styleClass="form-control datetimepicker"
converter="localDateConverter"
disabled="true"
value="#{listaContaPagar.contaAPagar.datasLancamentoFinanceiro.dataVencimento}">
</h:inputText>
</div>
</div>
<!--Data de Pagamento-->
<div class="col-xs-12 col-sm-6 col-md-3 form-group">
<label for="dataPagamento"><span
style="color: red">*</span>Data do Pagamento</label>
<div class="fg-line">
<h:inputText id="dataPagamento"
styleClass="form-control datetimepicker"
converter="localDateConverter"
converterMessage="Data de Pagamento inválida!"
value="#{listaContaPagar.contaAPagar.datasLancamentoFinanceiro.dataBaixa}"
pt:placeholder="__/__/____"/>
</div>
</div>
<!--Numero de Documento-->
<div class="col-xs-12 col-sm-6 col-md-3 form-group">
<label for="numeroDocumento">
Número do Documento
</label>
<div class="fg-line">
<h:inputText id="numeroDocumento" disabled="true"
styleClass="form-control"
value="#{listaContaPagar.contaAPagar.numeroDocumento}"/>
</div>
</div>
<!--Tipo de Documento-->
<div class="col-xs-12 col-sm-6 col-md-3 form-group" style="height: 58px;">
<label for="tipoDocumentoDespesa">
Tipo do Documento
</label>
<div class="fg-line">
<h:inputText id="tipoDocumentoDespesa" disabled="true"
styleClass="form-control"
value="#{listaContaPagar.contaAPagar.tipoDocumento.descricao}"/>
</div>
</div>
</div>
<!--Taxa e Valores-->
<div class="row">
<div class="col-xs-12 m-b-15">
<h2 class="label-title no-margin">
<i class="icon-dollar-circle"> </i> Taxas e Valores
</h2>
</div>
<!--Valor do Documento-->
<div class="col-xs-12 col-sm-6 col-md-3 form-group">
<label for="valorDocumento">
<span style="color: red">*</span>
Valor do Documento
</label>
<div class="fg-line">
<h:inputText id="valorDocumento" converter="#{moneyConverter}"
styleClass="input-money form-control"
pt:placeholder="R$ 0,00" disabled="true"
value="#{listaContaPagar.contaAPagar.valoresLancamentosFinanceiro.valorDocumento}">
</h:inputText>
</div>
</div>
<!--Juros-->
<div class="col-xs-12 col-sm-6 col-md-3 form-group">
<label for="valor_juros">
Juros
</label>
<div class="fg-line">
<h:inputText id="valor_juros" converter="#{moneyConverter}"
styleClass="input-money form-control"
pt:placeholder="R$ 0,00"
value="#{listaContaPagar.contaAPagar.valoresLancamentosFinanceiro.valorJuros}">
<p:ajax event="blur" process="@this"
listener="#{listaContaPagar.atualizarValorPago}"/>
</h:inputText>
</div>
</div>
<!--Multa-->
<div class="col-xs-12 col-sm-6 col-md-3 form-group">
<label for="valor_multa">
Multa
</label>
<div class="fg-line">
<h:inputText id="valor_multa" converter="#{moneyConverter}"
styleClass="input-money form-control"
pt:placeholder="R$ 0,00"
value="#{listaContaPagar.contaAPagar.valoresLancamentosFinanceiro.valorMulta}">
<p:ajax event="blur" process="@this"
listener="#{listaContaPagar.atualizarValorPago}"/>
</h:inputText>
</div>
</div>
<!--Desconto-->
<div class="col-xs-12 col-sm-6 col-md-3 form-group">
<label for="valor_desconto">
Desconto
</label>
<div class="fg-line">
<h:inputText id="valor_desconto" converter="#{moneyConverter}"
styleClass="input-money form-control"
pt:placeholder="R$ 0,00"
value="#{listaContaPagar.contaAPagar.valoresLancamentosFinanceiro.valorDesconto}">
<p:ajax event="blur" process="@this"
listener="#{listaContaPagar.atualizarValorPago}"/>
</h:inputText>
</div>
</div>
</div>
<!--Pagamentos-->
<div class="row">
<div class="col-xs-12 m-b-15">
<h2 class="label-title no-margin">
<i class="icon-money"> </i> Pagamentos
<p:commandLink styleClass="btn bgm-deeporange btn-icon"
onclick="abrirPagamento();">
<span class="icon-plus"> </span>
</p:commandLink>
</h2>
</div>
<div class="col-xs-12">
<p:dataTable id="tb_pagamentos" widgetVar="tb_pagamentos"
value="#{listaContaPagar.contaAPagar.pagamentos}"
var="pagamento" reflow="true" emptyMessage="Nenhum registro encontrado.">
<p:column headerText="Valor" styleClass="text-center">
<h:outputText
value="#{pagamento.valorPago}" converter="#{moneyConverter}">
</h:outputText>
</p:column>
<p:column headerText="Meio de Pagamento" styleClass="text-center">
<h:outputText value="#{pagamento.meioPagamento.descricao}"/>
</p:column>
<p:column headerText="Conta Financeira" styleClass="text-center">
<h:outputText value="#{pagamento.contaCaixa.nome}"/>
</p:column>
<p:column headerText="Situação" style="text-align: center;"
filterable="false" width="5%">
<h:panelGroup
styleClass="#{listaContaPagar.retornaSituacaoPagamento(pagamento)}"
style="width:20px; height:20px; border-radius: 50%; margin:auto;"
layout="block">
</h:panelGroup>
</p:column>
<p:column headerText="Ações" styleClass="text-center">
<p:commandLink
action="#{listaContaPagar.verificaPodeEditar}"
immediate="true">
<f:setPropertyActionListener value="#{pagamento}"
target="#{listaContaPagar.pagamentoAux}"/>
<span class="icon-pencil"> </span>
</p:commandLink>
<p:commandLink
action="#{listaContaPagar.verificaPodeEstonar}"
immediate="true">
<f:setPropertyActionListener value="#{pagamento}"
target="#{listaContaPagar.pagamentoAux}"/>
<span class="icon-rotate_left"> </span>
</p:commandLink>
</p:column>
</p:dataTable>
</div>
<h:panelGroup id="valor_aberto_pago" styleClass="col-xs-12">
<div class="col-md-3 col-md-offset-9">
<h:outputLabel value="Valor em Aberto: ">
<h:outputText
value="#{listaContaPagar.contaAPagar.valoresLancamentosFinanceiro.valorAberto}"
converter="#{moneyConverter}"/>
</h:outputLabel>
</div>
<div class="col-md-3 col-md-offset-9">
<h:outputLabel value="Valor Pago: ">
<h:outputText
value="#{listaContaPagar.contaAPagar.valoresLancamentosFinanceiro.valorPago}"
converter="#{moneyConverter}"/>
</h:outputLabel>
</div>
</h:panelGroup>
</div>
</div>
</h:panelGroup>
<div class="modal-footer">
<p:commandLink id="baixar_lancamento" styleClass="btn btn-primary"
actionListener="#{listaContaPagar.salvarDespesaImediata}">
<i class="icon-file-text"> </i> Salvar Despesa
</p:commandLink>
<a href="javascript:;" class="btn btn-default m-r-15"
onclick="$('#modal_baixa_lancamento').closeModal();">
<i class="icon-times"> </i> #{msg.btn_cancelar}
</a>
</div>
</h:form>
</div>
This modal above loads an object of type LancamentoFinanceiro
, I can add a list of payments (Value, account and payment method) when I add a payment the amount paid at launch is changed. The method below makes this change:
public void addPagamento() {
try {
if (!editarPagamento) {
if (regraBaixa.nao().satisfeitaPor(pagamentoAux)) {
throw new RegraDeNegocioExecption(regraBaixa.getDetails());
}
if (baixaSimples) {
contaAPagar = lancamentoFinanceiroService.addPagamento(contaAPagar, pagamentoAux);
if (contaAPagar.getValoresLancamentosFinanceiro().getValorAberto().doubleValue() < 0) {
qMessagesHelper.toastWarning(null, "Valor pago é maior que o valor do documento!", null);
}
} else {
baixaMultiplaLancamento = lancamentoFinanceiroService.addPagamento(baixaMultiplaLancamento, pagamentoAux);
if (baixaMultiplaLancamento.getValoresLancamentosFinanceiro().getValorAberto().doubleValue() < 0) {
qMessagesHelper.toastWarning(null, "Valor pago é maior que o valor do documento!", null);
}
}
pagamentoAux = new Pagamento();
} else {
editarPagamento = Boolean.FALSE;
contaAPagar.getValoresLancamentosFinanceiro().setValorPago(
lancamentoFinanceiroService.retornaSaldoPago(contaAPagar)
);
contaAPagar.getValoresLancamentosFinanceiro().setValorAberto(
lancamentoFinanceiroService.calculaVlrAberto(contaAPagar)
);
meioCartao = Boolean.FALSE;
}
//Updates nos Componentes
if (baixaSimples) {
facesUtil.updateComponente("tb_pagamentos panelPagamentos valor_aberto_pago");
} else {
facesUtil.updateComponente("baixaMultipla_tb_pagamentos panelPagamentos valor_aberto_pago_multipla");
}
facesUtil.executeScriptJS("ativaScripts();$('#modal_cad_pagamento').closeModal();");
} catch (RegraDeNegocioExecption e) {
for (QimobAlert s : e.getMessages()) {
qMessagesHelper.showQimobAlert(s);
}
} catch (Exception e) {
qMessagesHelper.toastWarning(null, e.getMessage(), null);
e.printStackTrace();
}
}
Service method that performs paid and open value calculation and returns the release with new set values in these fields:
public LancamentoFinanceiro addPagamento(LancamentoFinanceiro lancamento, Pagamento pagamentoAux) {
switch (pagamentoAux.getMeioPagamento()) {
case DINHEIRO:
pagamentoAux.setSituacao(SituacaoLancamento.CONCILIADO);
break;
default:
pagamentoAux.setSituacao(SituacaoLancamento.BAIXADO);
break;
}
Integer index = isRepetido(pagamentoAux, lancamento);
if (index != null) {
lancamento.getPagamentos().get(index)
.setValorPago(lancamento.getPagamentos().get(index).getValorPago()
.add(pagamentoAux.getValorPago()));
} else {
lancamento.addPagamento(pagamentoAux);
}
lancamento.getValoresLancamentosFinanceiro().setValorPago(lancamento.getValoresLancamentosFinanceiro().getValorPago()
.add(pagamentoAux.getValorPago()));
lancamento.getValoresLancamentosFinanceiro().setValorAberto(calculaVlrAberto(lancamento));
return lancamento;
}
after performing this operation it returns to the Modal displayed in the first code. The user has the option to Save, or Cancel. If it clicks on save Ok, it will do all the process I want and performs the update in the Bank. But even if I cancel, or simply click outside the Modal it performs the bank update, even though there is no persitence/update action associated with these actions.
Entity:
@Entity
@Table(name = "tb_lancamento_financeiro")
@XmlRootElement
public class LancamentoFinanceiro extends BaseEntity {
...
@OneToMany(mappedBy = "lancamentoFinanceiro", orphanRemoval = true)
private List<Pagamento> pagamentos;
...
}
Update Method:
public void update(Object entity) throws RepositorioException, JaExisteException, NaoExisteException {
if (entity == null) {
throw new RepositorioException("Entidade informada é nula");
} else {
try {
entityManager.merge(entity);
} catch (NoResultException e) {
throw new NaoExisteException(e.getMessage());
} catch (PersistenceException e) {
Throwable t = e.getCause();
while ((t != null) && !(t instanceof ConstraintViolationException)) {
t = t.getCause();
}
if (t instanceof ConstraintViolationException) {
throw new JaExisteException(e.getMessage());
} else {
throw new RepositorioException(e.getMessage());
}
} catch (Exception e) {
throw new RepositorioException(e.getMessage());
}
}
}
Are you using the Hibernate object directly on the screen? The ideal would be to have a model for the screen (vision), which we call Viewmodel, and then after all the controller validations, the Hibernate object would be updated with the data of the new object. Note that if you want to use a Hibernate object directly on the interface, you will need to control the Hibernate session out of of the interface, only to give the final commit after going through the controller methods. However, your question lacks quality as it does not have a minimum and viable example to understand the context.
– Loudenvier
The structure is this. There is the entity(Model) mapped, the controller and service layer. The point is that it is simply ignoring all the layers and performing the update directly in the bank. Not even in the method that my Entitymanager performs Merge it passes. About the example I don’t know what to put because it already goes straight to the bank, but I will at least print where it should be passing.
– Jhonatan Mota
Jhonatan, do you have any session management? What kind of application is it? Do you use any framework? An example in . NET session management on ASP.NET: http://joseoncode.com/2011/03/effective-nhibernate-session-management-for-web-apps/ . So it’s clear that you need to know what kind of application it is (desktop, mobile, web) and the framework, if any, being used.
– Loudenvier
The project is Java web (JSF 2). I put some snippets of code above to see if it can better clarify the problem.
– Jhonatan Mota
I don’t think the problem is with your classes themselves, but rather with Hibernate session management. As I have no JSF experience I can’t help more than that. Someone with experience should come along and, with our conversation and the new data you put in the question, they should be able to answer you! But I bet, again, that session management is to blame for that!
– Loudenvier
Perhaps one of these questions answered in the Stack Overflow has its answer: http://stackoverflow.com/questions/7848769/is-this-a-right-pattern-for-hibernate-session-transaction-management , or, http://stackoverflow.com/questions/23802226/hibernate-session-handling-when-using-Lazy-loading-in-a-jsf-web-application
– Loudenvier
Thank you. I will check the links indicated.
– Jhonatan Mota