2011-09-19 61 views
0

我有两个有多对多关系的类(学生和课程)。 它们的实例可以在没有其他实例的情况下存在。 因此,我删除了JPA注释中的级联属性:@ManyToMany(cascade = CascadeType.ALL)使用MANY_TO_MANY关系删除对象的一个​​实例,没有级联失败

一旦我尝试删除学生,我会收到此错误消息。

我在做什么错?

org.hibernate.exception.ConstraintViolationException:无法 删除:[com.Student#4];嵌套的异常是 javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException:无法 删除:[com.Student#4]

这是休眠输出:

休眠:删除学生在哪里id =?和版本=? 2011-09-19 15:25:10317 [HTTP-8080-3] ERROR org.hibernate.util.JDBCExceptionReporter - 不能删除或更新 父行:外键约束失败 (databasestudent_course,约束FKF8A06F72970A31AF外国 KEY(students)参考文献studentsid))

这些都是类的相关部分:

@RooJavaBean 
@RooToString 
@RooEntity 
public class Student{ 

    @ManyToMany 
    private Set<Course> courses= new HashSet<Course>(); 
} 

@RooJavaBean 
@RooToString 
@RooEntity 
public class Course { 

    @ManyToMany(mappedBy = "courses") 
    private Set<Student> students= new HashSet<Student>(); 
} 
+0

您的意图是什么?如果你是_deleting_“学生”,你一定希望所有课程中的“Set”都被更新,对吗?尝试恢复级联,但使用'CascadeType.REMOVE' – millhouse

+0

您可以在删除学生之前尝试清除课程集合。我不认为级联会在这里帮助 - 级联是删除学生时删除课程。你的情况是什么导致问题是映射表中的行。 – gkamal

回答

1

我正想建议将detachFromCourses()方法添加到您的Student中,该方法会遍历courses,删除this。你会在删除Student之前调用它。但这很丑,并且与Spring Roo不太吻合。

我可以建议看看创建一个JPA Entity Listener迷上了@PreRemove JPA事件吗?然后,您可以保持您的域模型和您的控制器免于数据库特定的东西。您的实体听众可以这样做:

@PreRemove 
void onPreRemove(Object o) { 
    if (o instanceof Student) { 
     // Remove all the course references to this Student 
     Student s = (Student) o; 
     for (Course c : s.getCourses()) { 
      c.getStudents().remove(s); 
     } 
    } 
} 
+0

尽管您的方法非常好,但您提供的代码会导致StackOverflowException,因为onPreRemove会一遍又一遍地被触发。 – Hedge

相关问题