在休眠中使用一对一关系删除

Delete using One to one relation in hibernate

由于我是 hibernate 的新手并且我使用的是 hibernate 4 版本。以下代码包含使用注释的一对一关系的简单示例。当我尝试删除父对象时,抛出外键约束异常。我对如何实现这一目标感到困惑和困惑。尽管我一直使用级联类型。纠正错误

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;


   @Entity
   @Table(name="students")

public class Student {
@Id
@Column(name="student_id")
private long studentId=0;

@Column(name="sname",length=15)
private String studentName=null;

@Column(name="grp",length=15)
private String grp=null;

public long getStudentId() {
    return studentId;
}

public void setStudentId(long studentId) {
    this.studentId = studentId;
}

public String getStudentName() {
    return studentName;
}

public void setStudentName(String studentName) {
    this.studentName = studentName;
}

public String getGrp() {
    return grp;
}

public void setGrp(String grp) {
    this.grp = grp;
}
}

这是用于在数据库中插入和更新的父级 class。

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Column;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Id;
import javax.persistence.Table;


   @Entity
   @Table(name="address")

public class Address {
@Id
@Column(name="address_id")
private long addressId=0;

@Column(name="place",length=30)
private String place=null;

@OneToOne(targetEntity=Student.class,fetch=FetchType.EAGER , cascade=CascadeType.ALL, orphanRemoval=true)
@JoinColumn(name="stud_id",referencedColumnName="student_id")

private Student parent;

public long getAddressId() {
    return addressId;
}

public void setAddressId(long addressId) {
    this.addressId = addressId;
}

public String getPlace() {
    return place;
}

public void setPlace(String place) {
    this.place = place;
}

public Student getParent() {
    return parent;
}

public void setParent(Student parent) {
    this.parent = parent;
}
}

下面是删除对象的方法。但是我得到了例外。如何删除与父对象关联的子记录?

public void deleteStudentDao(long studentId) throws Exception{
    Session session=null;
    try{

        if(studentId >0 && factory!=null 
                && !factory.isClosed()){
            session=factory.openSession();
            session.beginTransaction();

            Student student=new Student();
            student.setStudentId(studentId);

            Address address=new Address();
            address.setParent(student);

            session.delete(address);
            session.getTransaction().commit();
            System.out.println("The Student "+studentId+" detail deleted");
        }
    }catch(HibernateException e){
        session.getTransaction().rollback();
        throw e;
    }finally{
        if(session!=null){
            session.close();
        }
    }
}

例外是

ERROR: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`address`, CONSTRAINT `FK_4ok3rcn3mnfl5ma2wuwvkluuo` FOREIGN KEY (`stud_id`) REFERENCES `students` (`student_id`))
    Mar 10, 2017 10:50:34 AM org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl release
    INFO: HHH000010: On release of batch it still contained JDBC statements
    org.hibernate.exception.ConstraintViolationException: could not execute statement
        at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:72)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:211)
    at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:62)
    at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3400)
    at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3630)
    at org.hibernate.action.internal.EntityDeleteAction.execute(EntityDeleteAction.java:114)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:463)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:349)
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1222)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425)
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177)
    at com.mv.dao.StudentDetailDAO.deleteStudentDao(StudentDetailDAO.java:98)
    at com.mv.studentutil.StudentRelationalUtil.deleteStudentUtil(StudentRelationalUtil.java:56)
    at com.mv.studentmodifier.StudentModifier.main(StudentModifier.java:54)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`address`, CONSTRAINT `FK_4ok3rcn3mnfl5ma2wuwvkluuo` FOREIGN KEY (`stud_id`) REFERENCES `students` (`student_id`))
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:408)
    at com.mysql.jdbc.Util.getInstance(Util.java:383)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1049)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4226)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4158)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2615)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2776)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2840)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2082)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2334)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2262)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2246)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:208)
    ... 15 more

你不应该 delete 这样的地址。在您的案例中,您需要在学生和地址之间建立双向关系。

@Entity
@Table(name = "students")    
public class Student {
    ...    
    // Add this property with getter & setter methods in your Student class. 
    @OneToOne(mappedBy="parent")
    private Address address; 

   ...

}

现在,在你的删除方法中,根据其 Id 从数据库中获取学生实体,然后从学生实体中获取学生地址,然后删除地址实体。由于级联性质,这将删除地址和学生。

这是您可以尝试使用的代码:

try {

            if (studentId > 0 && factory != null && !factory.isClosed()) {
                session = factory.openSession();
                session.beginTransaction();

                Student student = (Student) session.get(Student.class, studentId);
                session.delete(student.getAddress());

                /*Student student=new Student();
                student.setStudentId(studentId);

                Address address=new Address();
                address.setParent(student);

                session.delete(address);*/

                session.getTransaction().commit();
                System.out.println("The Student " + studentId + " detail deleted");
            }