0

嗨,我有部门实体,在那个部门实体中,我在字符串数据类型中有一个名为部门名称的属性,另一个属性parentdepartment(一对多)作为部门数据类型(类类型)作为该列的外键。我使用了一个-to -many 关系和 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();
4

1 回答 1

0

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

考虑到

  • 父母 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 ;

[编辑] 请参阅DELETE_ORPHAN 和 DELETE 有什么区别?

事实是,孤儿删除将在从父子集合中删除子实体时删除它们。

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

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

于 2014-03-14T09:13:51.927 回答