Hibernate JPA级联删除问题

Hibernate JPA级联删除问题,hibernate,class,entity,jpa-2.0,Hibernate,Class,Entity,Jpa 2.0,为了解释我的问题,我创建了这个带有两个表的简单项目:item和order1(item的orderId是外键) 现在,当我试图从订单表中删除一行时,我得到一个错误,即特定的订单id与“item”表中的几个项目链接 因此,我要做的是迭代所有的item对象(使用'Eager'加载),并为每个对象调用destroy()。删除所有项目后,我调用order.destroy()。 但现在,我得到了以下错误: Exception in thread "main" javax.persistence.Rollba

为了解释我的问题,我创建了这个带有两个表的简单项目:item和order1(item的orderId是外键)

现在,当我试图从订单表中删除一行时,我得到一个错误,即特定的订单id与“item”表中的几个项目链接

因此,我要做的是迭代所有的item对象(使用'Eager'加载),并为每个对象调用destroy()。删除所有项目后,我调用order.destroy()。 但现在,我得到了以下错误:

Exception in thread "main" javax.persistence.RollbackException: Error while commiting the transaction
        at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:71)
        at     com.sourind.test.testorm.controller.ItemJpaController.destroy(ItemJpaController.java:112)
        at com.sourind.test.testorm.App.main(App.java:31)
Caused by: org.hibernate.ObjectDeletedException: deleted entity passed to persist:     [com.sourind.test.testorm.entity.Item#<null>]
}

以及order1类:

@Entity
@Table(name = "order", catalog = "test", schema = "")
@NamedQueries({
    @NamedQuery(name = "Order1.findAll", query = "SELECT o FROM Order1 o"),
    @NamedQuery(name = "Order1.findById", query = "SELECT o FROM Order1 o WHERE o.id = :id"),
    @NamedQuery(name = "Order1.findByOrderDate", query = "SELECT o FROM Order1 o WHERE o.orderDate = :orderDate")})
public class Order1 implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;
    @Basic(optional = false)
    @Column(name = "orderDate")
    @Temporal(TemporalType.TIMESTAMP)
private Date orderDate;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "order1", fetch=FetchType.EAGER)
private List<Item> itemList;

public Order1() {
}

public Order1(Integer id) {
    this.id = id;
}

public Order1(Integer id, Date orderDate) {
    this.id = id;
    this.orderDate = orderDate;
}

public Integer getId() {
    return id;
}

public void setId(Integer id) {
    this.id = id;
}

public Date getOrderDate() {
    return orderDate;
}

public void setOrderDate(Date orderDate) {
    this.orderDate = orderDate;
}

public List<Item> getItemList() {
    return itemList;
}

public void setItemList(List<Item> itemList) {
    this.itemList = itemList;
}

@Override
public int hashCode() {
    int hash = 0;
    hash += (id != null ? id.hashCode() : 0);
    return hash;
}

@Override
public boolean equals(Object object) {
    // TODO: Warning - this method won't work in the case the id fields are not set
    if (!(object instanceof Order1)) {
        return false;
    }
    Order1 other = (Order1) object;
    if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
        return false;
    }
    return true;
}

@Override
public String toString() {
    return "com.sourind.test.testorm.entity.Order1[id=" + id + "]";
}
@实体
@表(name=“order”、catalog=“test”、schema=”“)
@命名查询({
@NamedQuery(name=“Order1.findAll”,query=“从Order1 o中选择o”),
@NamedQuery(name=“Order1.findById”,query=“从Order1中选择o,其中o.id=:id”),
@NamedQuery(name=“Order1.findByOrderDate”,query=“从Order1中选择o,其中o.orderDate=:orderDate”)}
公共类Order1实现可序列化{
私有静态最终长serialVersionUID=1L;
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
@基本(可选=假)
@列(name=“id”)
私有整数id;
@基本(可选=假)
@列(name=“orderDate”)
@时态(TemporalType.TIMESTAMP)
私有日期orderDate;
@OneToMany(cascade=CascadeType.ALL,mappedBy=“order1”,fetch=FetchType.EAGER)
私人清单项目清单;
公共秩序1(){
}
公共订单1(整数id){
this.id=id;
}
公共医嘱1(整数id、日期医嘱日期){
this.id=id;
this.orderDate=orderDate;
}
公共整数getId(){
返回id;
}
公共无效集合id(整数id){
this.id=id;
}
公共日期getOrderDate(){
退货日期;
}
公共作废setOrderDate(日期orderDate){
this.orderDate=orderDate;
}
公共列表getItemList(){
返回项目列表;
}
公共无效集合项目列表(列表项目列表){
this.itemList=itemList;
}
@凌驾
公共int hashCode(){
int hash=0;
hash+=(id!=null?id.hashCode():0);
返回散列;
}
@凌驾
公共布尔等于(对象){
//TODO:警告-如果未设置id字段,此方法将不起作用
if(!(Order1的对象实例)){
返回false;
}
Order1 other=(Order1)对象;
如果((this.id==null&&other.id!=null)| |(this.id!=null&&!this.id.equals(other.id))){
返回false;
}
返回true;
}
@凌驾
公共字符串toString(){
返回“com.sourind.test.testorm.entity.Order1[id=“+id+”]”;
}
}

提前感谢,,
Souri

您应该能够删除订单记录,并让它删除所有相关的项目记录。为此,您需要向订单和项目之间的关联添加另一个级联类型

@OneToMany(cascade=CascadeType.ALL, mappedBy = "order1", fetch=FetchType.EAGER, orphanRemoval=true)
private List<Item> itemList;

此删除操作将级联到子项记录并删除它们。

@Alex以下是
ItemJpaController\destroy()的代码。

而且,我使用的hibernate版本没有
DELETE\u ORPHAN
cascade类型


另外,我如何获得会话?我应该在
JpaController
方法中的
JpaController
类中,还是在我创建/删除对象的mail方法中获得它?

你能从ItemJpaController#destroy()方法中发布代码吗?这看起来应该是对原始问题的编辑。如果是的话,你能修改/标记一个版主为你做这件事吗。啊,我明白了。我猜只有在使用Hibernate内核时,注释才可用。您可以按如下方式从实体管理器获取会话:session session=entityManager.unwrap(session.class);你可以这样使用deleteonforn:@OneToMany(deleteonforn=true)我认为这对JPA有用。很抱歉,没有发现您正在直接使用EntityManager。遇到同样的问题,尝试删除父实体并将删除级联到所属实体。无论如何,我已经包含了注释@Cascade(org.hibernate.annotations.CascadeType.DELETE_orphant),并且我从NetBeans收到了一条警告:DELETE_orphant CascadeType已被弃用。我使用的是Hibernate3.6,但它似乎并没有解决这个问题。在JPA中删除是相当痛苦的。在很多情况下,它都能像预期的那样工作,还有一些情况让我感到困惑不已。实际上,你应该在OneToMany中使用orphanRemoving=true来避免不推荐的问题。我已经编辑了我的答案来解决这个问题。
@OneToMany(cascade=CascadeType.ALL, mappedBy = "order1", fetch=FetchType.EAGER, orphanRemoval=true)
private List<Item> itemList;
session.delete(order);
public void destroy(Integer id) throws NonexistentEntityException {
    EntityManager em = null;
    try {
        em = getEntityManager();
        em.getTransaction().begin();
        Item item;
        try {
            item = em.getReference(Item.class, id);
            item.getId();
        } catch (EntityNotFoundException enfe) {
            throw new NonexistentEntityException("The item with id " + id + " no longer exists.", enfe);
        }
        Order1 order1 = item.getOrder1();
        if (order1 != null) {
            order1.getItemList().remove(item);
            order1 = em.merge(order1);
        }
        em.remove(item);
        em.getTransaction().commit();
    } finally {
        if (em != null) {
            em.close();
        }
    }
}