孤儿删除不起作用

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 因为它是多余的。

【讨论】:

以上是关于孤儿删除不起作用的主要内容,如果未能解决你的问题,请参考以下文章

TableView 滑动删除不起作用

为啥使用 sed 删除不起作用?

Sharedpreferences 删除不起作用

从核心数据中删除记录不起作用?

JavaFX 属性删除侦听器不起作用

ios7删除照片不起作用