Error running function for the second time

4

Inside the controller I have this function:

public void salvaEncaminhamento() {
    Integer qtdEncaminhamento = 0;

    if (manifestacao.getTbEncaminhamentoCollection() != null) {
        qtdEncaminhamento = manifestacao.getTbEncaminhamentoCollection().size();
    }

    TbUsuario usuario = securityService.getUser();
    for(String idUnidadeStr : idOrgaoDestino) {
        try {
            int idUnidade = Integer.parseInt(idUnidadeStr);

            //atualiza data de modificacao da manifestacao
            manifestacao.setDtUltimaAtualizacao(new Date());
            //atualiza status da manifestacao caso ela ainda esteja como nova
            if (manifestacao.getStStatusManifestacao().equals(StatusManifestacaoEnum.EM_ANALISE.getId()) || manifestacao.getStStatusManifestacao().equals(StatusManifestacaoEnum.SOLICITACAO_RESPONDIDA.getId())) {
                manifestacao.setStStatusManifestacao(StatusManifestacaoEnum.EM_ANDAMENTO.getId());
                dao.edit(manifestacao);
            }

            /*-----------------------------------------------------*/
            /*------- inicio - gravando encaminhamento ------------*/
            /*-----------------------------------------------------*/
            TbEncaminhamento encaminhamento = new TbEncaminhamento();
            encaminhamento.setDsDescricao(dsEncaminhamento);
            encaminhamento.setDtCriacaoEncaminhamento(new Date());
            encaminhamento.setDtEnvioTramite(new Date());
            encaminhamento.setIdManifestacao(manifestacao);
            encaminhamento.setIdUsuarioEnviou(usuario);
            encaminhamento.setIdUnidadeEnviou(usuario.getIdUnidade());
            encaminhamento.setStEncaminhamento(StatusEncaminhamentoEnum.ENCAMINHADA.getId());

            TbUnidade unidade = unidadeDAO.find(idUnidade);
            encaminhamento.setIdUnidadeRecebeu(unidade);

            encaminhamentoDAO.create(encaminhamento);
            qtdEncaminhamento++;
            /*------- fim - gravando encaminhamento ------------*/


            /*-----------------------------------------------------*/
            /*------- inicio - gravando tramite -------------------*/
            /*-----------------------------------------------------*/
            TbTramite tramite = new TbTramite();
            tramite.setDsDescricao(dsEncaminhamento);
            tramite.setDtTramite(new Date());
            tramite.setIdEncaminhamento(encaminhamento);
            tramite.setIdUnidadeEnvio(unidade);
            tramite.setIdUsuarioEmissor(usuario);
            tramite.setStRetornada(BooleanEnum.NAO.getId());
            tramite.setStNotificacao(BooleanEnum.NAO.getId());
            tramite.setStTramitePublico(BooleanEnum.NAO.getId());

            TbUsuario usuarioReceptor = null;
            if (ValidacaoHelper.isNotEmpty(idUsuarioEncaminhamento)) {
                usuarioReceptor = usuarioDAO.find(idUsuarioEncaminhamento);
                tramite.setIdUsuarioReceptor(usuarioReceptor);
            }
            tramiteDAO.create(tramite);

            //----- gravando anexos ---------//
            ArrayList<TbTramitexAnexo> anexosTramite = new ArrayList<>();
            for (TbAnexo anexo : arquivosEncaminhamento) {
                anexoDAO.create(anexo);
                TbTramitexAnexo tbTramitexAnexo = new TbTramitexAnexo();
                tbTramitexAnexo.setIdAnexo(anexo);
                tbTramitexAnexo.setIdTramite(tramite);
                anexosTramite.add(tbTramitexAnexo);
            }
            tramite.setTbTramitexAnexoCollection(anexosTramite);
            tramiteDAO.edit(tramite);
            /*------- fim - gravando tramite ------------*/

            try {
                enviarEmailsEncaminhamento(unidade, usuarioReceptor);
                //----- enviando e-mail ao MANIFESTANTE ---------//
                if (qtdEncaminhamento == 1) {
                    EmailService.Email emailManifestante = emailService.newEmail();
                    if ((manifestacao.getEeEmailUsuario() != null) && "1".equals(manifestacao.getStResposta())) {

                        String nomeManifestante = (manifestacao.getNmPessoa() != null) ? manifestacao.getNmPessoa() : "Manifestante";
                        emailManifestante.addDestinatario(nomeManifestante, manifestacao.getEeEmailUsuario());

                        TbEmailAutomatizado emailAutomatizado = emailAutomatizadoDAO.findByTipo(EmailAutomatizadoEnum.PRIMEIRO_TRAMITE);

                        //adiciona texto e assunto de email padrao
                        StringBuilder emailTextoHtml = new StringBuilder();
                        StringBuilder emailTexto = new StringBuilder();

                        emailManifestante.setAssunto(PalavrasChavesHelper.converterPalavrasChaves(emailAutomatizado.getNmTituloEmail(), manifestacao, false));
                        emailTextoHtml.append(PalavrasChavesHelper.converterPalavrasChaves(emailAutomatizado.getDsEmail(), manifestacao, false));
                        emailTexto.append(PalavrasChavesHelper.converterPalavrasChaves(emailAutomatizado.getDsEmail(), manifestacao, false));

                        emailManifestante.setTextoHtml(emailTextoHtml.toString());
                        emailManifestante.setTextoSemFormatacao(emailTexto.toString());
                        emailService.envia(emailManifestante);
                    }
                }
                MensagemFaceUtil.info("Manifestação encaminhada com sucesso.", "Manifestação encaminhada com sucesso.");
            } catch (Exception e) {
                e.printStackTrace();
                MensagemFaceUtil.alerta("Manifestação encaminhada mas não possível notiticar por e-mail.", "O seu encaminhamento foi realizado com sucesso porém, não foi possível notificar os envolvidos por e-mail.");
            }
        } catch (Exception e) {
            e.printStackTrace();
            MensagemFaceUtil.erro("Erro ao encaminhar Manifestação.", e.getMessage());
        }
    }

    ajustaListaStatusManifestacao();
    preparaListaAreasSolucionadoras();
    mountTabs();
    //zerando variaveis
    idUnidadeEncaminhamento = null;
    idUsuarioEncaminhamento = null;
    mensagemEncaminhamento = null;
    dsEncaminhamento = null;
    idEncaminhamentoPadronizado = null;
    arquivosEncaminhamento = new ArrayList<>();

    showRedirectPageModal();
}

It is called when a manifestation is forwarded to a unit, but at the first forwarding everything happens ok, but if I try to forward a second manifestation to the same organ this returns the catch message of "Error while forwarding Manifestation."

The log prints the following error:

13:50:46,298 WARN  [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http--127.0.0.1-8080-2) SQL Error: 0, SQLState: 23505
13:50:46,298 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http--127.0.0.1-8080-2) ERROR: duplicate key value violates unique constraint "uk_6w9ft31ycpj6j9pf1b17k8nw2"
  Detalhe: Key (tbclassificacao_idclassificacao)=(2177) already exists.
13:50:46,300 ERROR [stderr] (http--127.0.0.1-8080-2) javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement
13:50:46,300 ERROR [stderr] (http--127.0.0.1-8080-2)    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1387)

And after that it follows with a lot of generic messages that do not even fit here in the text box, but can be seen here: link

The tbClassification that is in the log is this:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.xti.ouvidoria.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

/**
 *
 * @author samuel.guimaraes
 */
@Entity
@Table(name = "tbClassificacao")
@NamedQueries({
    @NamedQuery(name = "TbClassificacao.findAll", query = "SELECT t FROM TbClassificacao t"),
    @NamedQuery(name = "TbClassificacao.findByIdClassificacao", query = "SELECT t FROM TbClassificacao t WHERE t.idClassificacao = :idClassificacao"),
    @NamedQuery(name = "TbClassificacao.findByUnidade", query = "SELECT t FROM TbClassificacao t WHERE :idUnidade MEMBER OF t.tbUnidadeCollection"),
    @NamedQuery(name = "TbClassificacao.findByDsClassificacao", query = "SELECT t FROM TbClassificacao t WHERE t.dsClassificacao = :dsClassificacao")})
public class TbClassificacao implements Serializable, Comparable<TbClassificacao> {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "idClassificacao")
    private Integer idClassificacao;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 180)
    @Column(name = "dsClassificacao")
    private String dsClassificacao;
    @OneToMany
    private Collection<TbUnidade> tbUnidadeCollection = new ArrayList<>();
    @OneToMany
    @JoinTable(
            name="tbClassificacao_tbSubClassificacao",
            joinColumns={@JoinColumn(name="TbClassificacao_idClassificacao", referencedColumnName="idClassificacao")},
            inverseJoinColumns={@JoinColumn(name="tbSubClassificacaoCollection_idSubClassificacao", referencedColumnName="idSubClassificacao")})
    private Collection<TbSubClassificacao> tbSubClassificacaoCollection = new ArrayList<>();
    @OneToMany
    @JoinTable(
            name="tbManifestacao_tbClassificacao",
            joinColumns={@JoinColumn(name="tbClassificacao_idClassificacao", referencedColumnName="idClassificacao")},
            inverseJoinColumns={@JoinColumn(name="TbManifestacao_idManifestacao", referencedColumnName="idManifestacao")})
    private Collection<TbManifestacao> tbManifestacaoCollection = new ArrayList<>();


    public Collection<TbUnidade> getTbUnidadeCollection() {
        return tbUnidadeCollection;
    }

    public Collection<TbManifestacao> getTbManifestacaoCollection() {
        return tbManifestacaoCollection;
    }

    public void setTbManifestacaoCollection(Collection<TbManifestacao> tbManifestacaoCollection) {
        this.tbManifestacaoCollection = tbManifestacaoCollection;
    }

    public void setTbUnidadeCollection(Collection<TbUnidade> tbUnidadeCollection) {
        this.tbUnidadeCollection = tbUnidadeCollection;
    }

    public TbClassificacao() {
    }

    public TbClassificacao(Integer idClassificacao) {
        this.idClassificacao = idClassificacao;
    }

    public TbClassificacao(Integer idClassificacao, String dsClassificacao) {
        this.idClassificacao = idClassificacao;
        this.dsClassificacao = dsClassificacao;
    }

    public Integer getIdClassificacao() {
        return idClassificacao;
    }

    public void setIdClassificacao(Integer idClassificacao) {
        this.idClassificacao = idClassificacao;
    }

    public String getDsClassificacao() {
        return dsClassificacao;
    }

    public void setDsClassificacao(String dsClassificacao) {
        this.dsClassificacao = dsClassificacao;
    }

    public Collection<TbSubClassificacao> getTbSubClassificacaoCollection() {
        return tbSubClassificacaoCollection;
    }

    public void setTbSubClassificacaoCollection(Collection<TbSubClassificacao> tbSubClassificacaoCollection) {
        this.tbSubClassificacaoCollection = tbSubClassificacaoCollection;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (idClassificacao != null ? idClassificacao.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        if (!(object instanceof TbClassificacao)) {
            return false;
        }
        TbClassificacao other = (TbClassificacao) object;
        if ((this.idClassificacao == null && other.idClassificacao != null) || (this.idClassificacao != null && !this.idClassificacao.equals(other.idClassificacao))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return String.format("%s > %s", getEntidade(), getDescricao());
    }

    private String getEntidade() {
        return "Classificação";
    }

    private String getDescricao() {
        return dsClassificacao;
    }

    @Override
    public int compareTo(TbClassificacao o) {
        return getDsClassificacao().toUpperCase().compareTo(o.getDsClassificacao().toUpperCase());
    }
}

I'm surprising a lot, at first it was to be a project they are using and it should be just install and use. If anyone wants to check out the project it's this: link

Update!

Through the comments and some tests I found a code in the initial data load script found in their own project that deletes and then manually creates the tbclassificacao_tbunidade , table that performs a join with tbclassificacao and where the error occurs.

--Acertos nos mapeamentos gerados

DROP TABLE tbclassificacao_tbunidade;

CREATE TABLE tbclassificacao_tbunidade
(
  tbclassificacao_idclassificacao integer NOT NULL,
  tbunidadecollection_idunidade integer NOT NULL,
  CONSTRAINT fk107ce929d7b9b0e FOREIGN KEY (tbclassificacao_idclassificacao)
      REFERENCES tbclassificacao (idclassificacao) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT fk107ce92d27d48b9 FOREIGN KEY (tbunidadecollection_idunidade)
      REFERENCES tbunidade (idunidade) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT tbclassificacao_tbunidade_tbclassificacao_idclassificacao_key UNIQUE (tbclassificacao_idclassificacao, tbunidadecollection_idunidade)
)
WITH (
  OIDS=FALSE
); 

Note: Without running this command, it does not compile.

    
asked by anonymous 04.09.2017 / 19:14

1 answer

2

Well, with a lot of analysis and help from everyone who commented on it, the error in the fact that in the tbmanifestacao_tbclassificacao table the tbclassificacao_idclassificacao field could not be required to be UNIQUE because more than one manifestation with a selected classification equal can be routed to the same unit and this table stores the chosen classification with respect to manifestation.

So I tested the table creation by removing all these dependencies, and the routing worked.

As it was:

-- Table: public.tbmanifestacao_tbclassificacao

-- DROP TABLE public.tbmanifestacao_tbclassificacao;

CREATE TABLE public.tbmanifestacao_tbclassificacao
(
  tbmanifestacao_idmanifestacao integer NOT NULL,
  tbclassificacao_idclassificacao integer NOT NULL,
  CONSTRAINT fk_6w9ft31ycpj6j9pf1b17k8nw2 FOREIGN KEY (tbclassificacao_idclassificacao)
      REFERENCES public.tbclassificacao (idclassificacao) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT fk_jbkoiljnamdf9icojnuxaskby FOREIGN KEY (tbmanifestacao_idmanifestacao)
      REFERENCES public.tbmanifestacao (idmanifestacao) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT uk_6w9ft31ycpj6j9pf1b17k8nw2 UNIQUE (tbclassificacao_idclassificacao),
  CONSTRAINT uk_jbkoiljnamdf9icojnuxaskby UNIQUE (tbmanifestacao_idmanifestacao)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE public.tbmanifestacao_tbclassificacao
  OWNER TO postgres;

How I did it:

-- Table: public.tbmanifestacao_tbclassificacao

-- DROP TABLE public.tbmanifestacao_tbclassificacao;

CREATE TABLE public.tbmanifestacao_tbclassificacao
(
  tbmanifestacao_idmanifestacao integer NOT NULL,
  tbclassificacao_idclassificacao integer NOT NULL,
  CONSTRAINT fk_6w9ft31ycpj6j9pf1b17k8nw2 FOREIGN KEY (tbclassificacao_idclassificacao)
      REFERENCES public.tbclassificacao (idclassificacao) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT fk_jbkoiljnamdf9icojnuxaskby FOREIGN KEY (tbmanifestacao_idmanifestacao)
      REFERENCES public.tbmanifestacao (idmanifestacao) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT uk_jbkoiljnamdf9icojnuxaskby UNIQUE (tbmanifestacao_idmanifestacao)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE public.tbmanifestacao_tbclassificacao
  OWNER TO postgres;
    
11.09.2017 / 21:39