Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Duplicação no persist

Boa tarde, estou com um projeto utilizando SpringMVC e Hibernate, mas o problema é que tenho 3 classes Terminal Navio Viagem

dentro da classe Terminal tenho um List de Navio dentro da classe Navio tenho um HashSet de Viagem o problema é que a classe viagem esta sendo duplicada no banco de dados, justamente o motivo de eu usar um HashSet...

@Entity
public class Navio implements Comparable<Navio>,Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 2728365026163871299L;
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="navio_id")
    private Long id;

    private String nome;

    @ManyToOne
    @JoinColumn(name = "terminal_id")
    private Terminal terminal;

    @OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
    private Set<Viagem> viagens = new HashSet<>();


    public void setViagens(Set<Viagem> viagens) {
        this.viagens = viagens;
    }
    @Deprecated
    public Navio(){};
    public Navio(String nome, Viagem viagem) {
        if (nome == null || viagem == null) {
            throw new NullPointerException();
        }
        this.nome = nome;
        viagens.add(viagem);
    }

    public Navio(String nome) {
        if (nome == null) {
            throw new NullPointerException();
        }
        this.nome = nome;
    }

    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public Terminal getTerminal() {
        return terminal;
    }
    public void setTerminal(Terminal terminal) {
        this.terminal = terminal;
    }

    public Set<Viagem> getViagens() {
        return Collections.unmodifiableSet(viagens);
    }

    public void addViagem(Viagem outraViagem) {
        outraViagem.setNavio(this);
        if(!(outraViagem==(null)) && (!this.viagens.contains(outraViagem))){
            this.viagens.add(outraViagem);
        }
    }
    public void addViagens(Set<Viagem> listaDeViagens){
        for (Viagem viagem : listaDeViagens) {
            addViagem(viagem);
        }
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public int compareTo(Navio outroNavio) {
        return this.getNome().compareTo(outroNavio.getNome());
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((nome == null) ? 0 : nome.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Navio other = (Navio) obj;
        if (nome == null) {
            if (other.nome != null)
                return false;
        } else if (!nome.equals(other.nome))
            return false;
        return true;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("Nome do Navio: " + this.nome);
        for (Viagem viagem : this.viagens) {
            sb.append(System.lineSeparator() + viagem);
        }
        return sb.toString();
    }
}
@Entity
public class Terminal implements Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 6682770195622648303L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="terminal_id")
    private Long id;
    private String nome;

    @OneToMany(cascade=CascadeType.ALL,mappedBy="terminal")
    private List<Navio> navios = new ArrayList<>();

    public String getNome() {
        return nome;
    }

    public void setNome(String terminal) {
        this.nome = terminal.toString();
    }

    public List<Navio> getNavios() {
        return Collections.unmodifiableList(navios);
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public void setNavios(List<Navio> navios) {
        this.navios = navios;
    }

    public boolean isNameEquals(String nome) {
        return this.nome.equals(nome);
    }

    public void addNavio(Navio navio) {
        navio.setTerminal(this);
        if (this.navios.contains(navio)) {
            navios.get(navios.indexOf(navio)).addViagens(navio.getViagens());
        } else {
            navios.add(navio);
        }
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((navios == null) ? 0 : navios.hashCode());
        result = prime * result + ((nome == null) ? 0 : nome.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Terminal other = (Terminal) obj;
        if (navios == null) {
            if (other.navios != null)
                return false;
        } else if (!navios.equals(other.navios))
            return false;
        if (nome == null) {
            if (other.nome != null)
                return false;
        } else if (!nome.equals(other.nome))
            return false;
        return true;
    }

    public void addNavios(List<Navio> navios) {
        for (Navio navio : navios) {
            addNavio(navio);
        }
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(this.nome+System.lineSeparator());
        for (Navio navio : navios) {
            sb.append("Navio: "+navio.getNome()+System.lineSeparator());
            for (Viagem viagem : navio.getViagens()) {
                sb.append("Viagem: "+viagem.getDtChegada() + "/" + viagem.getSituacao()+System.lineSeparator());
            }
        }
        return sb.toString();
    }
}
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name = "viagem_id")
    private Long id;

    @ManyToOne
    @JoinColumn(name="navio_id")
    private Navio navio;

    private String nomeViagem;

    @Temporal(TemporalType.DATE)
    private Calendar prevDtChegada;
    @Temporal(TemporalType.DATE)
    private Calendar dtChegada;
    @Temporal(TemporalType.DATE)
    private Calendar prevDtAtracacao;
    @Temporal(TemporalType.DATE)
    private Calendar dtAtracacao;
    @Temporal(TemporalType.DATE)
    private Calendar prevDtSaida;
    @Temporal(TemporalType.DATE)
    private Calendar dtSaida;
    @Temporal(TemporalType.DATE)
    private Calendar inicioOperacao;
    @Temporal(TemporalType.DATE)
    private Calendar terminoOperacao;

    private String agencia;
    private int embarcados;
    private int desembarcados;
    private int removidos;
    private String servico;

    private String situacao;


    @Deprecated
    public Viagem(){};
    public Viagem(String situacao,Calendar dtChegada) {
        this.situacao = situacao;
        this.dtChegada = dtChegada;
    }
    public String getNomeViagem() {
        return nomeViagem;
    }
    public void setNomeViagem(String nomeViagem) {
        this.nomeViagem = nomeViagem;
    }
    public Calendar getPrevDtChegada() {
        return prevDtChegada;
    }
    public void setPrevDtChegada(Calendar prevDtChegada) {
        this.prevDtChegada = prevDtChegada;
    }
    public Calendar getDtChegada() {
        return dtChegada;
    }
    public void setDtChegada(Calendar dtChegada) {
        this.dtChegada = dtChegada;
    }
    public Calendar getPrevDtAtracacao() {
        return prevDtAtracacao;
    }
    public void setPrevDtAtracacao(Calendar prevDtAtracacao) {
        this.prevDtAtracacao = prevDtAtracacao;
    }
    public Calendar getDtAtracacao() {
        return dtAtracacao;
    }
    public void setDtAtracacao(Calendar dtAtracacao) {
        this.dtAtracacao = dtAtracacao;
    }
    public Calendar getPrevDtSaida() {
        return prevDtSaida;
    }
    public void setPrevDtSaida(Calendar prevDtSaida) {
        this.prevDtSaida = prevDtSaida;
    }
    public Calendar getDtSaida() {
        return dtSaida;
    }
    public void setDtSaida(Calendar dtSaida) {
        this.dtSaida = dtSaida;
    }
    public Calendar getInicioOperacao() {
        return inicioOperacao;
    }
    public void setInicioOperacao(Calendar inicioOperacao) {
        this.inicioOperacao = inicioOperacao;
    }
    public Calendar getTerminoOperacao() {
        return terminoOperacao;
    }
    public void setTerminoOperacao(Calendar terminoOperacao) {
        this.terminoOperacao = terminoOperacao;
    }
    public String getAgencia() {
        return agencia;
    }
    public void setAgencia(String agencia) {
        this.agencia = agencia;
    }
    public int getEmbarcados() {
        return embarcados;
    }
    public void setEmbarcados(int embarcados) {
        this.embarcados = embarcados;
    }
    public int getDesembarcados() {
        return desembarcados;
    }
    public void setDesembarcados(int desembarcados) {
        this.desembarcados = desembarcados;
    }
    public int getRemovidos() {
        return removidos;
    }
    public void setRemovidos(int removidos) {
        this.removidos = removidos;
    }
    public String getServico() {
        return servico;
    }
    public void setServico(String servico) {
        this.servico = servico;
    }
    public String getSituacao() {
        return situacao;
    }
    public void setSituacao(String situacao) {
        this.situacao = situacao;
    }
    public static long getSerialversionuid() {
        return serialVersionUID;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + desembarcados;
        result = prime * result + ((dtAtracacao == null) ? 0 : dtAtracacao.hashCode());
        result = prime * result + ((dtChegada == null) ? 0 : dtChegada.hashCode());
        result = prime * result + ((dtSaida == null) ? 0 : dtSaida.hashCode());
        result = prime * result + ((inicioOperacao == null) ? 0 : inicioOperacao.hashCode());
        result = prime * result + ((prevDtAtracacao == null) ? 0 : prevDtAtracacao.hashCode());
        result = prime * result + ((prevDtChegada == null) ? 0 : prevDtChegada.hashCode());
        result = prime * result + ((prevDtSaida == null) ? 0 : prevDtSaida.hashCode());
        result = prime * result + ((terminoOperacao == null) ? 0 : terminoOperacao.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Viagem other = (Viagem) obj;
        if (desembarcados != other.desembarcados)
            return false;
        if (dtAtracacao == null) {
            if (other.dtAtracacao != null)
                return false;
        } else if (!dtAtracacao.equals(other.dtAtracacao))
            return false;
        if (dtChegada == null) {
            if (other.dtChegada != null)
                return false;
        } else if (!dtChegada.equals(other.dtChegada))
            return false;
        if (dtSaida == null) {
            if (other.dtSaida != null)
                return false;
        } else if (!dtSaida.equals(other.dtSaida))
            return false;
        if (inicioOperacao == null) {
            if (other.inicioOperacao != null)
                return false;
        } else if (!inicioOperacao.equals(other.inicioOperacao))
            return false;
        if (prevDtAtracacao == null) {
            if (other.prevDtAtracacao != null)
                return false;
        } else if (!prevDtAtracacao.equals(other.prevDtAtracacao))
            return false;
        if (prevDtChegada == null) {
            if (other.prevDtChegada != null)
                return false;
        } else if (!prevDtChegada.equals(other.prevDtChegada))
            return false;
        if (prevDtSaida == null) {
            if (other.prevDtSaida != null)
                return false;
        } else if (!prevDtSaida.equals(other.prevDtSaida))
            return false;
        if (terminoOperacao == null) {
            if (other.terminoOperacao != null)
                return false;
        } else if (!terminoOperacao.equals(other.terminoOperacao))
            return false;
        return true;
    }
    @Override
    public String toString() {
        return  "{"+nomeViagem +  ", agencia=" + agencia + ", embarcados=" + embarcados + ", desembarcados="
                + desembarcados + ", removidos=" + removidos + ", servico=" + servico + ", situacao=" + situacao + 
                System.lineSeparator()+", prevDtChegada=" + prevDtChegada.getTimeInMillis() +System.lineSeparator()+ ", dtChegada=" + dtChegada
                + System.lineSeparator()+", prevDtAtracacao=" + prevDtAtracacao +System.lineSeparator()+ ", dtAtracacao=" + dtAtracacao + System.lineSeparator()+", prevDtSaida="
                + prevDtSaida + System.lineSeparator()+", dtSaida=" + dtSaida + System.lineSeparator()+", inicioOperacao=" + inicioOperacao + System.lineSeparator()+", terminoOperacao="
                + terminoOperacao +"}";
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public Navio getNavio() {
        return navio;
    }
    public void setNavio(Navio navio) {
        this.navio = navio;
    }
public class TerminalDAO {

    @PersistenceContext
    private EntityManager manager;

    public List<Terminal> listar(){
        return manager.createQuery("select distinct(t) from Terminal t join fetch t.navios n where n.terminal.id = t.id",Terminal.class).getResultList();
    }
    private boolean isRegistered(Terminal terminal){
        try{
            find(terminal);
            return true;
        }catch(NoResultException e){
            return false;
        }
    }
    public void add(Terminal terminal) {
        if(isRegistered(terminal)){
            Terminal terminalDB = find(terminal);
            terminalDB.addNavios(terminal.getNavios());
        }else{
            manager.persist(terminal);
        }
        manager.flush();
    }
    private Terminal find(Terminal terminal) {
        return manager.createQuery("select distinct(t) from Terminal t where nome=:nome",Terminal.class).setParameter("nome", terminal.getNome()).getSingleResult();
    }
2 respostas

Oi Lucas, realmente tem muito código aí :). O meu chute é que o problema ta no equals e hashcode da sua classe viagem.. se eles tiverem com problema, o set vai aceitar objetos duplicados, pq na verdade o equals dele realmente não está batendo.

solução!

Desculpa pela lista de codigo, então o equals estava dando como true e mesmo assim estava sendo adicionado, isso tudo fazendo o persist da classe terminal, que possui uma lista de navios, sendo que navios possui um HashSet de Viagens, oque estava me intrigando é que mesmo a viagem dando true pro equals, não sendo inserido, no HashSet, pois verifiquei isso tambem, ele fazia o insert assim mesmo, não sei porque, mas ao fazer o persist do Navio tudo funcionou como deveria.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software