Erro ao inserir em cascata [RESOLVIDO]

1 resposta
jrfercar

Boa tarde.

Tenho duas classes, uma UnidadeFederativa e outra Pais, como segue:

UnidadeFederativa

@Entity
@Table(name = "unidadesfederativas")
public class UnidadeFederativa extends Entidade {

    @Column(nullable = false)
    private String nome;
    @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL, optional = false)
    @JoinColumn(name = "pais", referencedColumnName = "id", nullable = false)
    private Pais pais;
    @OneToMany(mappedBy = "unidadeFederativa", fetch= FetchType.LAZY, cascade = CascadeType.ALL)
    private List<Cidade> cidades;

Pais

@Entity
@Table(name = "paises")
public class Pais extends Entidade {

    @Column(nullable = false)
    private String nome;
    @OneToMany(mappedBy = "pais", fetch= FetchType.LAZY, cascade = CascadeType.ALL)
    private List<UnidadeFederativa> unidadesFederativas;

E possuo um método salvar em outra classe DAO, como segue:

public T salvar(T object) {
        getEntityManager().clear();

        getEntityManager().persist(object);

        return object;
    }

Em um Bean eu tenho um método chamado Cadastrar, como segue:

public void cadastrar(ActionEvent event) {
        Object value = null;

        if ((value = paisDao.pesqParam("Select p From Pais p Where p.nome = '" + pais.getNome() + "'")) != null) {
            pais = (Pais) value;
        }

        if ((value = unidadeFederativaDao.pesqParam("Select u From UnidadeFederativa u Where u.nome = '" + uf.getNome() + "' and u.pais.id = '" + pais.getId() + "'")) == null) {
            uf.setPais(pais);
            uf = unidadeFederativaDao.salvar(uf);
        } else {
            uf = (UnidadeFederativa) value;
        }

        if (uf != null) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("A Unidade Federal foi incluído com sucesso!"));
            
            init();
        
        } else {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("O logradouro não foi incluído!"));
        }
    }

O problema é que quando cadastro um país e uma unidade federativa pela primeira vez, o objeto é gravado no banco numa boa, porém, quando tento salvar uma nova unidade federativa para um país já cadastrado, eu não consigo salvar. O java retorna o erro dizendo que uma entidade está tentando persistir.

detached entity passed to persist

Isto acontece apenas quando o cascade do atributo pais da classe UnidadeFederativa está setado para ALL.

Quando seto o cascade do atributo pais da classe UnidadeFederativa para REFRESH eu consigo gravar numa boa.

Será que estou fazendo algo errado na hora de persistir?

O JPA não insere apenas os registros que são necessários?

Alguém pode me ajudar?

Desde já agradeço.

1 Resposta

jrfercar

Beleza gente,

Consegui resolver.

O cascade.ALL deve ser colocado em apenas um lado do relacionamento, dessa forma:

@Entity
@Table(name = "unidadesfederativas")
public class UnidadeFederativa extends Entidade {

    @Column(nullable = false)
    private String nome;
    @ManyToOne(fetch = FetchType.EAGER) //<-----------
    @JoinColumn(name = "pais", referencedColumnName = "id", nullable = false)
    private Pais pais;

No atributo pais, o @ManyToOne não deve ficar com a especificação de cascade.ALL.
O cascade.ALL deve ficar apenas no @OneToMany do atributo unidadesFederativas.

@Entity
@Table(name = "paises")
public class Pais extends Entidade {

    @Column(nullable = false)
    private String nome;
    @OneToMany(mappedBy = "pais", fetch= FetchType.LAZY, cascade = CascadeType.ALL) //<----------
    private List<UnidadeFederativa> unidadesFederativas;

Beleza gente, espero que ajude quem precise.

Criado 18 de julho de 2011
Ultima resposta 18 de jul. de 2011
Respostas 1
Participantes 1