Delete-orphan在休眠中给出了Exception

时间:2014-03-14 06:07:28

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

您好我有部门实体,在该部门实体中我有属性的部门名称在字符串数据类型中,另一个属性 parentdepartment (一对多)作为部门数据类型(类型类型)作为外部该列的关键。我使用了一对多的关系船和孤儿删除=真。如果删除我的父部门我不想删除子部门因为这个原因我在这里使用了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

DeparmentEntity

/*
 * 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();

1 个答案:

答案 0 :(得分:0)

你确定一个部门可以有很多家长吗?不应该有很多孩子吗?

考虑

  • 父母0..1 ------------- *孩子
  • 您想要从父级子集合中移除子级部门(孤儿删除)

bi directionnal

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

unidirectionnal

@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属性),你必须确保自己没有孩子在删除父母之前没有引用。< / p>