0

Hi i have Department entity ,In that department entity I have property's called department name In string datatype and another property parentdepartment(one-to-many) as department datatype(Class Type) as the foreign key to that column.And I have used one-to -many relation ship and orphan-removal=true.If delete My parent department I don't want to delete child department for that reason I have used orpen-removal here but it is giving an exception as following.

Exception

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

Test code

Session s = NewHibernateUtil.getSessionFactory().openSession();
        long l = 1;
        Department d = (Department) s.get(Department.class, l);
        s.delete(d);
        s.beginTransaction().commit();
user3214269
  • 219
  • 2
  • 8
  • 23

1 Answers1

0

Are you sure a department can have many parent ? Shouldn't it have many childs instead ?

Considering

  • Parent 0..1 ------------- * Childs
  • you want to delete child department when removing it from parent childs collection (orphan removal)

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 ;

[edit] Please see What is the difference between DELETE_ORPHAN and DELETE?

The fact is that orphan removal will remove the childs entities when removing them from parent's childs collection.

Cascade delete will remove the childs when removing the parent.

but with bi-directionnal removing the parent won't remove automatically the foreign-key (parentDepartement attribute) in the childs, you must ensure yourself than childs don't have the reference before removing the parent.

Community
  • 1
  • 1
Gab
  • 7,869
  • 4
  • 37
  • 68
  • Here I don not want delete child department Ex:When I am adding the department first time I will add parent department as null, And while adding second time I will make my first department is the parent for second one by keeping the primary key of the first one and second department. – user3214269 Mar 14 '14 at 09:28
  • If u want further clarification please ask me I will clear to you. – user3214269 Mar 14 '14 at 09:29
  • Hi You got my requirement please explain me about your changes. – user3214269 Mar 14 '14 at 09:59
  • removed the cascade_all as you do not want to delete the childs when deleting parent dpt. On the bi-directionnal approach I think that you must set parentDpt attribute to create the relationship (owning side) on the other one just add a child in the parent childs collection – Gab Mar 14 '14 at 10:04
  • really still I am not understanding.what is the difference between Delete and orphan removal.Can u please explain with my example. – user3214269 Mar 14 '14 at 11:34
  • orphan removal : parent.getChilds().remove(someChild) => will trigger someChild deletion in database cascade delete : em.delete(parent) => will trigger all parent childs deletion in database – Gab Mar 14 '14 at 12:59
  • How to do delete the parent without deleting the child (making child as null referance) in the table. – user3214269 Mar 14 '14 at 13:06
  • * Delete the parent without deleting the child => no cascade delete. * Making child as null reference => do it manually : for (Department dpt : parent.getChilds()) { dpt.setParent(null); } em.delete(parent); – Gab Mar 14 '14 at 13:12
  • Thanks ,But In orphan-removal if I delete parent The corresponding child's also deleteing like cascde delete. – user3214269 Mar 14 '14 at 13:27
  • yes if you delete the parent, childs are indeed orphan (no more parent). delete-orphan imply cascade delete. but i didn't knew the orm handled it alone – Gab Mar 14 '14 at 13:33
  • usefull link http://stackoverflow.com/questions/9533676/jpa-onetomany-parent-child-reference-foreign-key – Gab Mar 14 '14 at 13:52
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/49786/discussion-between-user3214269-and-gab) – user3214269 Mar 15 '14 at 03:42
  • So for,every thing is fine.But confusion is when I have an Entity class and one more entity student.Here the parent is class and child is student.If I delete the class,Is it need to make the all child's(Students) null reference manually? – user3214269 Mar 15 '14 at 03:51
  • depend on who 'own' the relationship. In unidirectionnal OneToMany, the one side is the only one and so it own the relationship, so in this case no. Otherwwise in bi-directionnal OneToMany, the many side own the relationship and you need to update it before removing the one side. – Gab Mar 15 '14 at 17:19
  • http://stackoverflow.com/questions/2584521/in-a-bidirectional-jpa-onetomany-manytoone-association-what-is-meant-by-the-in – Gab Mar 15 '14 at 17:24