【问题标题】:Delete-orphan is giving Exception in hibernate删除孤儿在休眠中给出异常
【发布时间】:2014-03-14 06:07:27
【问题描述】:

嗨,我有部门实体,在那个部门实体中,我有一个名为部门名称的属性,字符串数据类型和另一个属性 parentdepartment(一对多)作为部门数据类型(类类型)作为外部该列的关键。我使用了一对多关系和 orphan-removal=true。如果删除我的父部门,我不想删除子部门,因为这个原因我在这里使用了 orpen-removal 但它是给出一个例外如下。

例外

SEVERE: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`department`, CONSTRAINT `FKA9601F72A15DD2FD` FOREIGN KEY (`parentdeparment_id`) REFERENCES `department` (`id`))
Mar 14, 2014 9:48:49 AM org.hibernate.event.def.AbstractFlushingEventListener performExecutions
SEVERE: Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:146)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
    at com.myapp.struts.Teast.main(Teast.java:20)
Caused by: java.sql.BatchUpdateException: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`department`, CONSTRAINT `FKA9601F72A15DD2FD` FOREIGN KEY (`parentdeparment_id`) REFERENCES `department` (`id`))
    at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:2028)
    at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1451)
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
    ... 8 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`department`, CONSTRAINT `FKA9601F72A15DD2FD` FOREIGN KEY (`parentdeparment_id`) REFERENCES `department` (`id`))
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
    at com.mysql.jdbc.Util.getInstance(Util.java:386)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1039)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3609)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3541)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2002)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2163)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2624)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2127)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2427)
    at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1980)
    ... 11 more

Exception in thread "main" org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:146)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
    at com.myapp.struts.Teast.main(Teast.java:20)
Caused by: java.sql.BatchUpdateException: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`department`, CONSTRAINT `FKA9601F72A15DD2FD` FOREIGN KEY (`parentdeparment_id`) REFERENCES `department` (`id`))
    at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:2028)
    at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1451)
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
    ... 8 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`department`, CONSTRAINT `FKA9601F72A15DD2FD` FOREIGN KEY (`parentdeparment_id`) REFERENCES `department` (`id`))
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
    at com.mysql.jdbc.Util.getInstance(Util.java:386)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1039)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3609)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3541)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2002)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2163)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2624)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2127)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2427)
    at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1980)
    ... 11 more
Java Result: 1

部门实体

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.myapp.struts;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;


import javax.persistence.Entity;
import javax.persistence.FetchType;

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;

//import org.hibernate.annotations.Cascade;
//import org.hibernate.annotations.CascadeType;
/**
 *
 * @author hyva
 */
@Entity
public class Department implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    public Set<Department> getChildsDpt() {
        return childsDpt;
    }

    public void setChildsDpt(Set<Department> childsDpt) {
        this.childsDpt = childsDpt;
    }
    private String departmaentname;
    private String daperthead;

    @OneToMany(mappedBy = "parentdeparment", orphanRemoval = true)
    private Set<Department> childsDpt = new HashSet<Department>();

    @ManyToOne(fetch = FetchType.LAZY)
    private Department parentdeparment;
//    public boolean addDepartment(Department d) {
//        return parentdeparment.add(d);
//    }

    public String getDepartmaentname() {
        return departmaentname;
    }

    public void setDepartmaentname(String departmaentname) {
        this.departmaentname = departmaentname;
    }

    public String getDaperthead() {
        return daperthead;
    }

    public void setDaperthead(String daperthead) {
        this.daperthead = daperthead;
    }

    public Long getId() {
        return id;
    }

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

    @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 Department)) {
            return false;
        }
        Department other = (Department) 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.myapp.struts.Department[ id=" + id + " ]";
    }


    public Department getParentdeparment() {
        return parentdeparment;
    }

    public void setParentdeparment(Department parentdeparment) {
        this.parentdeparment = parentdeparment;
    }
}

测试代码

Session s = NewHibernateUtil.getSessionFactory().openSession();
        long l = 1;
        Department d = (Department) s.get(Department.class, l);
        s.delete(d);
        s.beginTransaction().commit();

【问题讨论】:

  • 是的,它是重复的,但在这里我使用了一对多的关系,也没有卡明你可以只看代码并发表评论
  • 嗨,你能帮我吗

标签: java hibernate hibernate-mapping all-delete-orphan


【解决方案1】:

您确定一个部门可以有多个父级吗?它不应该有很多孩子吗?

考虑

  • 父母 0..1 ------------- * 孩子
  • 您想在从父子集合中删除子部门时删除子部门(孤立删除)

双向

@OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, mappedBy = "parentDpt", orphanRemoval = true, fetch = FetchType.LAZY)
private final Set<Department> childsDpt = new HashSet<Department>();

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "parent_id")
private Department parentDpt;

单向

@OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, orphanRemoval = true)
@JoinColumn(name = "parent_id", referencedColumnName = "id")
private Set<Department> childsDpt ;

[编辑] 请看What is the difference between DELETE_ORPHAN and DELETE?

事实上,当从父级的子级集合中删除子实体时,孤儿删除将删除它们。

级联删除将在删除父级时删除子级。

但是通过双向删除父项不会自动删除子项中的外键(parentDepartement 属性),您必须确保自己比子项在删除父项之前没有引用。

【讨论】:

  • 这里我不想删除子部门 例如:当我第一次添加部门时,我会将父部门添加为空,而第二次添加时,我会让我的第一个部门成为第二个的父部门一个通过保留第一个和第二个部门的主键。
  • 如果你想进一步澄清,请问我,我会告诉你的。
  • 您好,您有我的要求,请解释一下您的更改。
  • 删除了 cascade_all,因为您不想在删除父 dpt 时删除子级。在双向方法上,我认为您必须设置 parentDpt 属性以在另一个上创建关系(拥有方),只需在父子集合中添加一个子节点
  • 我真的还是不明白。删除和孤儿删除有什么区别。你能用我的例子解释一下吗。
猜你喜欢
  • 2012-02-07
  • 2010-11-21
  • 2018-02-23
  • 2011-03-17
  • 2011-01-02
  • 2012-10-22
  • 1970-01-01
  • 2010-09-23
  • 2014-10-07
相关资源
最近更新 更多