Erro ao excluir com JPA e EJB [RESOLVIDO]

3 respostas
jrfercar

Bom dia,

estou com um problema para excluir um registro em uma tabela com uma associação reflexiva (diagrama de classe em anexo).
A estrutura em questão é composta das seguintes tabelas e classes:

Tabela Menu:

CREATE  TABLE Menus(
  id VARCHAR(32) NOT NULL ,

  nome VARCHAR(45) NULL ,

  command VARCHAR(45) NULL ,

  menu VARCHAR(32) NULL ,

  constraint pkyMenu PRIMARY KEY (`id`) ,
  constraint fkyMenuMenu FOREIGN KEY (menu) references menus(id))

Classe Menu:

@Entity
@Table(name = "menus")
public class Menu implements Serializable {
    @Id
    @GeneratedValue(generator="system-uuid")
    @GenericGenerator(name="system-uuid", strategy="uuid")
    @Column(name="id", unique=true, nullable=false, length=32)
    private String id;
    @Column(nullable = false)
    private String nome;
    private String command;
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "menu", referencedColumnName = "id", nullable = true)
    private Menu menu;
    @OneToMany(mappedBy = "menu", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private List<Menu> menus;

Classe Dao:

public class DaoGenericoImp<T, ID extends Serializable> implements DaoGenerico<T, ID> {

    @PersistenceContext(unitName = "adminsoftPU")
    private EntityManager entityManager;
    private Class<T> oClass = null;

    @SuppressWarnings("unchecked")
    public DaoGenericoImp() {
        this.oClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }

    @Override
    public Class<T> getObjectClass() {
        return this.oClass;
    }

    @SuppressWarnings("unchecked")
    public void setEntityManager(EntityManager em) {
        this.entityManager = em;
    }

    public EntityManager getEntityManager() {
        if (entityManager == null) {
            throw new IllegalStateException("Erro");
        }

        return entityManager;
    }

    @Override
    public void excluir(T object) {
        object = getEntityManager().merge(object);
        getEntityManager().remove(object);
        getEntityManager().flush();
    }
}

Classe CadastroDeMenuBean:

@ManagedBean
@ViewScoped
public class CadastroDeMenuBean implements Serializable {

    @EJB
    private MenuDao menuDao;
    private Menu menu;
    private Menu bMenu;
    private Menu menuPai;
    private List<Menu> menus;
    private List<Menu> menusCadastrados;
    private Boolean boolInserir;
    private Boolean boolAtualizar;
    private Boolean boolExcluir;
    private Boolean boolBuscar;

    public CadastroDeMenuBean() {
        init();
    }

    public Menu getMenu() {
        return menu;
    }

    public void setMenu(Menu menu) {
        this.menu = menu;
    }

    public Menu getbMenu() {
        return bMenu;
    }

    public void setbMenu(Menu bMenu) {
        this.bMenu = bMenu;
    }

    public Boolean getBoolAtualizar() {
        return boolAtualizar;
    }

    public void setBoolAtualizar(Boolean boolAtualizar) {
        this.boolAtualizar = boolAtualizar;
    }

    public Boolean getBoolBuscar() {
        return boolBuscar;
    }

    public void setBoolBuscar(Boolean boolBuscar) {
        this.boolBuscar = boolBuscar;
    }

    public Boolean getBoolExcluir() {
        return boolExcluir;
    }

    public void setBoolExcluir(Boolean boolExcluir) {
        this.boolExcluir = boolExcluir;
    }

    public Boolean getBoolInserir() {
        return boolInserir;
    }

    public void setBoolInserir(Boolean boolInserir) {
        this.boolInserir = boolInserir;
    }

    public List<Menu> getMenus() {
        if (menus == null) {
            menus = menuDao.listPesq("SELECT m FROM Menu m WHERE m.menu is null");

            menus.add(0, new Menu("Nenhum", null, null, null));
        }

        return menus;
    }

    public List<Menu> getMenusCadastrados() {
        if (menusCadastrados == null) {
            menusCadastrados = menuDao.listPesq("SELECT m FROM Menu m");
        }

        return menusCadastrados;
    }

    public void setMenus(List<Menu> menus) {
        this.menus = menus;
    }

    public Menu getMenuPai() {
        return menuPai;
    }

    public void setMenuPai(Menu menuPai) {
        this.menuPai = menuPai;
    }

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

        if ((value = menuDao.pesqParam("Select m From Menu m Where m.id = '" + menuPai.getId() + "'")) != null) {
            menu.setMenu((Menu) value);
        }

        menu = menuDao.salvar(menu);

        menus = null;

        if (menu != null) {
            FacesUtils.mensInfo("O menu foi incluído com sucesso!");

            init();

        } else {
            FacesUtils.mensInfo("O menu não foi incluído!");
        }
    }

    public void atualizar(ActionEvent event) {
        menu = menuDao.atualizar(menu);

        menus = null;

        if (menu != null) {
            FacesUtils.mensInfo("O menu foi incluído com sucesso!");

            init();

        } else {
            FacesUtils.mensInfo("O menu não foi incluído!");
        }
    }

    public void excluir(ActionEvent event) {
        menuDao.excluir(menu);
    }

    public void editar(Menu value) {
        menu = value;
        boolAtualizar = true;
        boolBuscar = false;
        boolExcluir = true;
        boolInserir = false;
    }

    public void buscar(ActionEvent event) {
        menusCadastrados = menuDao.listPesq("SELECT m FROM Menu m WHERE m.nome like '" + menu.getNome() + "%'");
    }

    public void limpar(ActionEvent event) {
        init();
    }

    private void init() {
        menusCadastrados = null;
        menu = new Menu();
        menuPai = new Menu();
        boolAtualizar = false;
        boolBuscar = true;
        boolExcluir = false;
        boolInserir = true;
    }
}

O grande problema é que quando eu executo o método excluir ocorre o seguinte erro e o registro não é excluido:

javax.persistence.EntityNotFoundException: deleted entity passed to persist: [br.adminsoft.model.persistence.entity.Menu#<null>]

Por isso peço a ajuda de vocês e agradeço desde já.

3 Respostas

Hebert_Coelho

Por acaso você não está passando um cara null ou então ainda não salvo na hora de excluir?

jrfercar

Obrigado pela força jakefrog,

a linha de erro deve ocorrer porque o registro que estou tentando apagar não possui nenhum menu filho associado.

Neste caso, como faço para que ele apague um registro que não precisa ter nenhum filho associado.

@Entity   
@Table(name = "menus")   
public class Menu implements Serializable {   
    @Id   
    @GeneratedValue(generator="system-uuid")   
    @GenericGenerator(name="system-uuid", strategy="uuid")   
    @Column(name="id", unique=true, nullable=false, length=32)   
    private String id;   
    @Column(nullable = false)   
    private String nome;   
    private String command;   
    @ManyToOne(fetch = FetchType.EAGER)   
    @JoinColumn(name = "menu", referencedColumnName = "id", nullable = true)   
    private Menu menu;   
    @OneToMany(mappedBy = "menu", fetch = FetchType.EAGER, cascade = CascadeType.ALL)   
    private List<Menu> menus;

Neste caso o atributo

private List<Menu> menus;

deve ser nulo mesmo.

jrfercar

Obrigado pessoal pela força.

Consegui resolver o problema retirando o cascade do atributo menus.

@OneToMany(mappedBy = "menu", fetch = FetchType.EAGER, cascade = CascadeType.ALL)     
    private List<Menu> menus;

ficando da seguinte forma:

@OneToMany(mappedBy = "menu", fetch = FetchType.EAGER)     
    private List<Menu> menus;
Criado 25 de novembro de 2011
Ultima resposta 30 de nov. de 2011
Respostas 3
Participantes 2