Alteração em Collections com o Hibernate [Resolvido]

Olá,

Estou com problemas ao alterar uma collection com o hibernate.

As classes envolvidas são as seguintes:

@Entity
@Table(name="descontos")
public class Desconto extends ModeloGenerico {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="cp_desconto")
    private int codigo;
    @OneToOne
    @JoinColumn(name="ce_produto")
    private Produto produto;
    @Column(name="tx_descricao")
    private String descricao;
    @Column(name="dt_inclusao")
    private Date dataInclusao;
    @Column(name="fg_permite_alteracao")
    private boolean permiteAlteracao;
    @OneToMany(cascade=CascadeType.ALL, mappedBy="desconto")
    private Set<Indice> indices;
    ...
@Entity
@Table(name="descontos_indices")
public class Indice implements Comparable<Indice>, Serializable{

    @Id
    @Column(name="vl_desconto")
    private double valor;
    @Id
    @ManyToOne
    @JoinColumn(name="ce_desconto")
    private Desconto desconto;
    @Column(name="vl_aliquota")
    private double aliquota;
    ...

Estou adicionando/alterando objetos da seguinte forma:

Transaction transacao = sessao.beginTransaction();
sessao.saveOrUpdate(objeto);
transacao.commit();

O problema acontece quando altero os indices de um objeto Desconto. Por exemplo: adiciono um desconto com 2 indices, depois altero este desconto (indices = new TreeSet()…) e deixo apenas 1 indice, quando salvo isso no banco é adicionado mais um indice na tabela de indices, mas eu gostaria que os indices anteriores fossem apagados.

Com o JDBC em casos como esse antes de alterar a tabela de descontos eu apagaria todos os indices e depois adicionaria de novo, com o Hibernate qual a melhor maneira de se fazer isso?

Obrigado.

Acho que este post tem a resposta para você: http://www.guj.com.br/java/211852-mapeamento-all-delete-orphan

Essa solução não funcionou pra mim.

No banco de dados, minha tabela descontos não possui referência a tabela de indices então não consigo mapear o relacionamento dessa maneira.

Tentei alterar a anotação da Collection para:

@OneToMany(cascade=CascadeType.ALL, mappedBy="desconto", orphanRemoval=true)
private Set&lt;Indice&gt; indices;

E agora recebo a seguinte exceção, que não consegui entender:
A collection with cascade=“all-delete-orphan” was no longer referenced by the owning entity instance

Obrigado.

Encontrei uma solução.

Resolvi o problema alterando a anotação da Collection para:

@OneToMany(cascade=CascadeType.ALL, mappedBy="desconto", orphanRemoval=true)
private Set<Indice> indices;

Percebi que o problema era que eu não deveria instanciar um novo Set e atribui-lo a a um índice e sim atualizar o set de indices já criado, então modifiquei um pouco o construtor da classe Desconto e o método setIndices, ficando assim:

public Desconto() {
        permiteAlteracao = true;
        indices = new TreeSet<Indice>();
}

Método setIndice agora apenas adiciona os elementos de um outro Set

public void setIndices(Set<Indice> indices) {
        this.indices.clear();
        this.indices.addAll(indices);
}

Com isso consegui fazer o que precisava: ao adicionar uma nova lista de indices, remover os indices anteriores.

Feito isso eu comecei a receber a seguinte exceção ao tentar modificar um índice mantendo seus identificadores iguais:
‘a different object with the same identifier value was already associated with the session’

o que resolvi adicionando limpando a sessão antes de gravar o objeto:

sessao.clear();

Não sei se essa é a melhor solução, mas está funcionando pra mim.

1 curtida