2011-09-19 60 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

相關問題