Pessoal, gostaria de uma ajuda de vcs no seguinte problema:
Tenho uma classe Perfil que possui relacionamento ManyToMany com Funcionalidade, tendo uma tabela associativa chamada PERFIL_FUNCIONALIDADE. Quando tento excluir o objeto perfil, preciso que os dados da tabela associativa também sejam excluidos, porém a tabela Funcionalidade permaneça intacta porque é uma tabela de domínio e seus dados nunca são apagados. Já usei o CascadeType mas o erro anexado abaixo bloqueia a exclusão logo de cara. Alguém poderia me ajudar?
Classe Perfil.java:
package entidades;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
@Entity
@Table(name = "PERFIL")
public class Perfil implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@SequenceGenerator(sequenceName = "SEQ_PERFIL", name = "SEQ_PERFIL", allocationSize=1)
@GeneratedValue(generator = "SEQ_PERFIL", strategy = GenerationType.SEQUENCE)
@Column(name = "ID_PERFIL")
private Long idPerfil;
@Column(name = "TX_NOME_PERFIL", length = 40, nullable = false)
private String nomePerfil;
@ManyToMany
@JoinTable(name = "PERFIL_FUNCIONALIDADE",
joinColumns = { @JoinColumn(name = "ID_PERFIL", nullable = false) },
inverseJoinColumns = { @JoinColumn(name = "CD_FUNCIONALIDADE", nullable = false) })
private List<Funcionalidade> funcionalidades = new ArrayList<Funcionalidade>();
...
}
Classe Funcionalidade.java:
package entidades;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
/**
* Tabela de dominio
* */
@Entity
@Table(name = "FUNCIONALIDADE")
public class Funcionalidade implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "CD_FUNCIONALIDADE")
private Long cdFuncionalidade;
@Column(name = "TX_NOME_FUNCIONALIDADE", nullable = false, length = 60)
private String nomeFuncionalidade;
@Column(name = "TX_URL", nullable = true, length = 2048)
private String url;
@ManyToMany(mappedBy = "funcionalidades")
private List<Perfil> perfis = new ArrayList<Perfil>();
...
}
Erro no console:
10:04:15,824 WARN [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http-localhost-127.0.0.1-8080-6) SQL Error: -532, SQLState: 23001
10:04:15,824 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http-localhost-127.0.0.1-8080-6) A parent row cannot be deleted because the relationship "DESENV.PERFIL_FUNCIONALIDADE.FK_PERFIL_FUNCIONALIDADE_PERFIL" restricts the deletion.. SQLCODE=-532, SQLSTATE=23001, DRIVER=4.12.79
10:04:15,847 WARNING [javax.enterprise.resource.webcontainer.jsf.lifecycle] (http-localhost-127.0.0.1-8080-6) #{perfilBean.excluir}:
excecao.DaoExcecao: excecao.DaoExcecao: Erro ao tentar excluir o perfil.: javax.faces.FacesException: #{perfilBean.excluir}: excecao.DaoExcecao: excecao.DaoExcecao: Erro ao tentar excluir o perfil.
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118) [jsf-impl-2.1.7-jbossorg-2.jar:]
at javax.faces.component.UICommand.broadcast(UICommand.java:315) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81) [jsf-impl-2.1.7-jbossorg-2.jar:]
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [jsf-impl-2.1.7-jbossorg-2.jar:]
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) [jsf-impl-2.1.7-jbossorg-2.jar:]
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
Classe PerfilEjb.java:
package ejbs;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.ejb.Local;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Local(IPerfilEjb.class)
@Stateless
public class PerfilEjb {
@PersistenceContext
private EntityManager manager;
private IPerfilDAO perfilDAO = new PerfilDAO();
private ILoginDAO loginDAO = new LoginDAO();
public List<String> excluirPerfis(Map<Long, Boolean> ids, Long idEntidade) throws DaoExcecao {
List<String> listaMensagens = new ArrayList<String>();
perfilDAO.setEntityManager(manager);
loginDAO.setEntityManager(manager);
List<Long> idsExcluir = new ArrayList<Long>();
Set<Entry<Long, Boolean>> idsSet = ids.entrySet();
for (Entry<Long, Boolean> e : idsSet) {
if (e.getValue()) {
if (loginDAO.verificarAssociacaoLoginPerfil(e.getKey(), idEntidade)) {
Perfil perfil = new Perfil();
perfil = perfilDAO.buscarPorId(e.getKey());
listaMensagens.add("Não foi possivel excluir o(s) perfil(s) " + perfil.getNomePerfil() + ". Existem usuários associados a esse perfil.");
} else {
idsExcluir.add(e.getKey());
}
}
}
if(!idsExcluir.isEmpty()) {
try{
perfilDAO.excluirPerfis(idsExcluir);
}catch(Exception e){
throw new DaoExcecao(e);
}
}
return listaMensagens;
}
}
Classe PerfilDAO.java:
package dao;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.transform.AliasToBeanResultTransformer;
public class PerfilDAO extends GenericDAO<Perfil, Serializable> implements IPerfilDAO {
public void excluirPerfis(List<Long> ids) throws DaoExcecao {
boolean primeiro = true;
try{
StringBuilder query = new StringBuilder();
query.append("DELETE FROM Perfil p ");
query.append(" WHERE p.idPerfil IN (");
for(Long id:ids){
if(!primeiro){
query.append(",");
}else{
primeiro = false;
}
query.append(id);
}
query.append(")");
((Session) getEntityManager().getDelegate()).createQuery(query.toString()).executeUpdate();
} catch (HibernateException e) {
throw new DaoExcecao("Erro ao tentar excluir o perfil.", e);
}
}
}