孤儿清除不起作用

时间:2015-06-18 05:41:10

标签: java sql jpa jdbc

我需要做下一个:当我删除一个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应用程序时起作用,但下一次尝试我得到了#34; SQLException语句回滚。&#34;

2 个答案:

答案 0 :(得分:0)

您尚未指定如何尝试实现持久/删除操作。 但是,根据您提供的信息,我创建了这个简化的示例:

派斯班:

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; }
}

DataAccess类:

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>

此代码适用于我。

不需要&#39; orphanRemoval&#39;,因为Pais对象在从数据库中获取后,已经有一个Estado对象列表。因此,当您删除此Pais对象时,所有关联的Estado对象也将被删除(级联)。

我在Win8.1上使用了Glassfish,JSF 2.2,Toplink和MySQL。

PS。帖子的标题有点令人困惑。

答案 1 :(得分:0)

@mmalik感谢你的例子,我已经在使用那种模型了。但问题在于持久性

出于某些奇怪的原因,NetBeans没有保存对持久性的更改。所以它没有保存以下属性。

<shared-cache-mode>NONE</shared-cache-mode>

对于其他任何事情都是正确的,只是观察到如果你定义orphanRemoval = true,你应该避免使用cascade = CascadeType.ALL,因为它是多余的。