删除具有MANY_TO_MANY关系且没有级联的对象实例失败

时间:2011-09-19 13:37:45

标签: hibernate spring spring-roo

我有两个课程(学生和课程),这些课程有多对多的关系。 它们的实例可以在没有其他实例的情况下存在。 因此我删除了JPA注释中的cascade-attribute:@ManyToMany(cascade = CascadeType.ALL)

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

我做错了什么?

  

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

这是Hibernate输出:

  

Hibernate:从id =?的学生中删除和版本=? 2011-09-19   15:25:10,317 [http-8080-3]错误   org.hibernate.util.JDBCExceptionReporter - 无法删除或更新   父行:外键约束失败   (databasestudent_course,CONSTRAINT 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>();
}

1 个答案:

答案 0 :(得分:1)

我打算建议在detachFromCourses()添加Student方法,该方法遍历courses,删除this。您可以在删除Student之前调用它。但这很难看,而且与Spring Roo不太匹配。

我是否可以建议创建一个与@PreRemove JPA活动相关联的JPA Entity Listener?然后,您可以保持您的域模型和控制器不受特定于数据库的限制。然后,您的实体监听器可以执行:

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