孤儿删除不起作用
Posted
技术标签:
【中文标题】孤儿删除不起作用【英文标题】:Orphan removal is not working 【发布时间】:2015-06-18 05:41:10 【问题描述】:我需要做下一个:当我删除一个 Parent 时,孩子也应该被删除。我正在使用 netbeans 嵌入式数据库,我正在阅读这个 orphanRemoval 参数,但对我不起作用,我真的不知道为什么。
家长:
@Entity
@Table(schema = "schema")
public class Pais implements Serializable
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name= "codigo", length=3)
private String codigo;
@Column(name= "nombre", length=100)
private String nombre;
@OneToMany(mappedBy = "pais", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Estado> estadoLista;
孩子:
@Entity
@Table(schema = "schema")
public class Estado implements Serializable
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name= "codigo", length=3)
private String codigo;
@Column(name= "nombre", length=100)
private String nombre;
@JoinColumn(name= "id_pais", referencedColumnName = "id")
@ManyToOne(optional = true)
private Pais pais;
@OneToMany(mappedBy = "Estado", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Municipio> municipioLista;
我真的想更具体一点,但我已经不明白为什么这不起作用。以防万一我包括我的坚持
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="JDCH-ejbPU" transaction-type="JTA">
<jta-data-source>jdbc/sample</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<shared-cache-mode>NONE</shared-cache-mode>
<properties>
<property name="javax.persistence.schema-generation.database.action" value="create"/>
</properties>
</persistence-unit>
</persistence>
更详细一点,它在我第一次部署和运行 Web 应用程序时工作,但下一次尝试我得到“SQLException statementroll back”。
【问题讨论】:
【参考方案1】:您尚未指定如何尝试实现持久/删除操作。 但是,根据您提供的信息,我创建了这个简化的示例:
派斯类:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.OneToMany;
@Entity (name = "Pais")
@Named
@RequestScoped
public class Pais implements Serializable
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column (name = "id")
private Long id;
@Column(name = "codigo")
private String codigo;
@Column(name = "nombre")
private String nombre;
@OneToMany(mappedBy = "pais", cascade = CascadeType.ALL)
private List<Estado> estadoLista;
public String create()
estadoLista = new ArrayList();
DataAccess data = new DataAccess();
Estado estado1 = new Estado("foo", "bar");
Estado estado2 = new Estado("foofoo", "barbar");
estadoLista.add(estado1);
estadoLista.add(estado2);
Pais pais = new Pais();
pais.setCodigo("test");
pais.setNombre("test1");
pais.setEstadoLista(estadoLista);
estado1.setPais(pais);
estado2.setPais(pais);
data.createPais(pais);
return "created";
public String delete()
DataAccess data = new DataAccess();
Pais pais = data.searchPaisByCodigo("test");
data.deletePais(pais);
return "deleted";
public void setId(Long id) this.id = id;
public Long getId() return id;
public void setCodigo(String codigo) this.codigo = codigo;
public String getCodigo() return codigo;
public void setNombre(String nombre) this.nombre = nombre;
public String getNombre() return nombre;
public void setEstadoLista(List<Estado> estadoLista) this.estadoLista = estadoLista;
public List<Estado> getEstadoLista() return estadoLista;
Estado 类:
import java.io.Serializable;
import java.util.List;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
@Entity (name = "Estado")
@Named
@RequestScoped
public class Estado implements Serializable
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column (name = "id")
private Long id;
@Column(name = "codigo", length=3)
private String codigo;
@Column(name = "nombre", length=100)
private String nombre;
@JoinColumn(name = "id_pais", referencedColumnName = "id")
@ManyToOne
private Pais pais;
Estado()
Estado(String codigo, String nombre)
this.codigo = codigo;
this.nombre = nombre;
public void setId(Long id) this.id = id;
public Long getId() return id;
public void setCodigo(String codigo) this.codigo = codigo;
public String getCodigo() return codigo;
public void setNombre(String nombre) this.nombre = nombre;
public String getNombre() return nombre;
public void setPais(Pais pais) this.pais = pais;
public Pais getPais() return pais;
数据访问类:
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
public class DataAccess
EntityManagerFactory emf = Persistence.createEntityManagerFactory("test");
EntityManager em = emf.createEntityManager();
public void createPais(Pais pais)
em.getTransaction().begin();
em.persist(pais);
em.getTransaction().commit();
public Pais searchPaisByCodigo(String codigo)
em.getTransaction().begin();
Query query = em.createQuery("select p from Pais p where p.codigo = :codigo");
query.setParameter("codigo", codigo);
Pais result = (Pais)query.getSingleResult();
em.getTransaction().commit();
return result;
public void deletePais(Pais pais)
em.getTransaction().begin();
em.remove(pais);
em.getTransaction().commit();
还有index.xhtml:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:form>
<h:commandButton value="Save" action="#pais.create" />
</h:form>
<br/>
<h:form>
<h:commandButton value="Delete" action="#pais.delete" />
</h:form>
</h:body>
</html>
这段代码对我来说很好用。
不需要“orphanRemoval”,因为 Pais 对象在从数据库中获取后,已经有一个 Estado 对象列表。因此,当您移除此 Pais 对象时,所有关联的 Estado 对象也会被移除(级联)。
我在 Win8.1 上使用了 Glassfish、JSF 2.2、Toplink 和 mysql。
PS。帖子的标题有点混乱。
【讨论】:
【参考方案2】:@mmalik 谢谢你的例子,我已经在使用这种模型了。但是问题在于持久性
出于某种奇怪的原因,NetBeans 没有保存对持久性的更改。所以它没有保存以下属性。
<shared-cache-mode>NONE</shared-cache-mode>
对于其他任何事情都是正确的,就像观察到如果你定义 orphanRemoval = true
你应该避免使用 cascade = CascadeType.ALL
因为它是多余的。
【讨论】:
以上是关于孤儿删除不起作用的主要内容,如果未能解决你的问题,请参考以下文章