Olá, estou começando a desenvolvedor com EJB. Eu criei uma entidade, um ManagedBean e um EJB. Consigo inserir e listar dados do banco, mas o meu método de deletar não dá erro, porém não deleta os dados do banco.
Entidade:
package br.com.teste.entidade;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Cliente {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
@Column
private String nome;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
}
ManagedBean:
package br.com.teste.managedbean;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import br.com.teste.ejb.ClienteBean;
import br.com.teste.entidade.Cliente;
@ManagedBean
@ViewScoped
public class ClienteMB {
private Cliente cliente = new Cliente();
private List<Cliente> lstCliente = new ArrayList<Cliente>();
public String incluirCliente(){
InitialContext ini;
try {
ini = new InitialContext();
ClienteBean clienteBean = (ClienteBean)ini.lookup("java:module/ClienteBean");
clienteBean.salvar(cliente);
cliente = new Cliente();
lstCliente = clienteBean.buscarCliente();
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public String deletarCliente(){
InitialContext ini;
try {
ini = new InitialContext();
ClienteBean clienteBean = (ClienteBean)ini.lookup("java:module/ClienteBean");
clienteBean.deletar(cliente);
cliente = new Cliente();
lstCliente = clienteBean.buscarCliente();
} catch (NamingException e) {
e.printStackTrace();
}
return null;
}
public Cliente getCliente() {
return cliente;
}
public void setCliente(Cliente cliente) {
this.cliente = cliente;
}
public List<Cliente> getLstCliente() {
return lstCliente;
}
public void setLstCliente(List<Cliente> lstCliente) {
this.lstCliente = lstCliente;
}
}
EJB:
package br.com.teste.ejb;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import br.com.teste.entidade.Cliente;
@Stateless
public class ClienteBean {
@PersistenceContext
EntityManager em;
public void salvar(Cliente cliente) {
em.persist(cliente);
}
public void deletar(Cliente cliente) {
em.remove(cliente);
}
public List<Cliente> buscarCliente(){
return em.createQuery("FROM Cliente").getResultList();
}
}
Já debugou para ver o que está acontecendo? Aparentemente você não está passando um cliente para ser deletado. O que está sendo enviado para o EJB é um cliente novo, instanciado na linha 19 do seu ClienteMB sem nenhum atributo preenchido.
Depende se a entidade é nova ou se ela está como DETACHED. Segue o que diz a especificação:[quote]A managed entity instance becomes removed by invoking the remove method on it or by cascading the
remove operation.
The semantics of the remove operation, applied to an entity X are as follows:
If X is a new entity, it is ignored by the remove operation. However, the remove operation is
cascaded to entities referenced by X, if the relationship from X to these other entities is annotated with the cascade=REMOVE or cascade=ALL annotation element value.
If X is a managed entity, the remove operation causes it to become removed. The remove operation is cascaded to entities referenced by X, if the relationships from X to these other entities
is annotated with the cascade=REMOVE or cascade=ALL annotation element value.
If X is a detached entity, an IllegalArgumentException will be thrown by the remove
operation (or the transaction commit will fail).
If X is a removed entity, it is ignored by the remove operation.
A removed entity X will be removed from the database at or before transaction commit or as a
result of the flush operation[/quote]
[quote=fredericomaia10]Já debugou para ver o que está acontecendo? Aparentemente você não está passando um cliente para ser deletado. O que está sendo enviado para o EJB é um cliente novo, instanciado na linha 19 do seu ClienteMB sem nenhum atributo preenchido.
[code] public String deletarCliente(Cliente cliente){
InitialContext ini;
try {
ini = new InitialContext();
ClienteBean clienteBean = (ClienteBean)ini.lookup("java:module/ClienteBean");
clienteBean.deletar(cliente);
cliente = new Cliente();
lstCliente = clienteBean.buscarCliente();
} catch (NamingException e) {
e.printStackTrace();
}
return null;
} [/code]
ps: sem ter ligação com o erro, está usando EJB remoto ou local?[/quote]
Eu tentei fazer o que você falou, mas não adiantou. Debugando, nem entra no método deletarCliente parece que o botão deletar está sem ação.
Estou usando EJB local.
Como eu disse, estou aprendendo sobre EJB, não sei se a forma que estou implementando está certo.
[quote=Viciado][quote=fredericomaia10]Agora entra o que o Rodrigo falou anteriormente. Sua entidade está detached.
Tente usar assim o método de deletar:
public void deletar(Cliente cliente) {
em.remove(em.find(cliente.getId());
}[/quote]
Obrigado. Funcionou!
Mais tarde, vou tentar fazer o método atualizar.
public void deletar(Cliente cliente) {
em.remove(em.find(Cliente.class, cliente.getId()));
}
[/quote]Troque o find por getReference. Ele melhora a performance, se quiser mais detalhes: http://uaihebert.com/?p=1622
[quote=Hebert Coelho][quote=Viciado][quote=fredericomaia10]Agora entra o que o Rodrigo falou anteriormente. Sua entidade está detached.
Tente usar assim o método de deletar:
public void deletar(Cliente cliente) {
em.remove(em.find(cliente.getId());
}[/quote]
Obrigado. Funcionou!
Mais tarde, vou tentar fazer o método atualizar.
public void deletar(Cliente cliente) {
em.remove(em.find(Cliente.class, cliente.getId()));
}
[/quote]Troque o find por getReference. Ele melhora a performance, se quiser mais detalhes: http://uaihebert.com/?p=1622[/quote]
OK. Valeu!
Para cada entidade que eu criar, vou ter que criar também um ManagedBean e um EJB ou posso ter genérico e ao ser chamado informar o nome da entidade?