在休眠中使用一对一关系删除
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");
}
由于我是 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");
}