2011-11-09 43 views
0

我有這樣的關係。有一個Car表和CarGroup表。汽車組表可容納汽車。我想要的是:當一輛汽車被拆除時,如果它在一個汽車組內,它應該像往常一樣從那裏拆除。我在我的項目中使用Spring和Hibernate(我有一個PostgreSQL數據庫)。當我想刪除一個車,我得到這個錯誤:Hibernate的DataIntegrityViolationException異常的外鍵違反不允許刪除

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not delete: [com.aaa.bbb.ccc.Car#2]; SQL [delete from Car where a_id=? and st=?]; constraint [fkbc80f56cb1ece7b8]; nested exception is org.hibernate.exception.ConstraintViolationException: could not delete: [com.aaa.bbb.ccc.Car#2] 
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:656) 
    org.springframework.web.servlet.FrameworkServlet.doDelete(FrameworkServlet.java:582) 
    javax.servlet.http.HttpServlet.service(HttpServlet.java:647) 
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:368) 
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109) 
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:112) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:169) 
    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237) 
    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167) 

我甚至無法從pgAdmin的(PostgreSQL的控制檯)刪除車像往常一樣。當我寫的是:

delete from Car where a_id=2 and st=2; 

錯誤,我得到如下:從我CarGroup

ERROR: update or delete on table "car" violates foreign key constraint "fkac80f56cb1ece7b8" on table "cargroup_car" 
DETAIL: Key (a_id)=(2) is still referenced from table "cargroup_car". 

********** Error ********** 

ERROR: update or delete on table "car" violates foreign key constraint "fkac80f56cb1ece7b8" on table "cargroup_car" 
SQL state: 23503 
Detail: Key (a_id)=(2) is still referenced from table "cargroup_car". 

部分代碼:

@ManyToMany(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}, fetch = FetchType.EAGER) 
    @JoinTable(name = "cargroup_car", joinColumns = @JoinColumn(name = "ADID"), inverseJoinColumns = @JoinColumn(name = "AID")) 
    private Set<Car> cars; 

編輯:我想:當我刪除一輛車,我想要它被刪除,即使它是在汽車組下。我不想刪除汽車組以刪除汽車。如何更改Java端數據庫設置(Cascade類型或將多對多更改爲多對一和多對多等)來執行此操作?

PS:我沒有寫Java端代碼。如果你解釋它,你是受歡迎的。

回答

1

您不能刪除汽車,因爲cargroup_car表中的一行有引用。因此,在刪除汽車之前,您需要刪除cargroup_car行。

+0

感謝。我的問題是如何配置Java端來完成它。我的意思是沒有必要刪除汽車組來刪除汽車。我能做些什麼與關係寫在汽車變量定義的頂部? – kamaci

+0

你是什麼意思?你必須刪除車組。你的數據庫就是這樣設置的。 – hvgotcodes

+0

@jb對,我認爲汽車組是連接表的原因... – hvgotcodes

0

只是一個猜測:嘗試添加CascadeType.REMOVE

@ManyToMany(cascade = 
    {CascadeType.REMOVE, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}, 
    fetch = FetchType.EAGER) 

或者存在其他選擇:你可以改變數據庫中的級聯外鍵約束從車上刪除操作cargroup,儘管它可能是危險的這樣做,這取決於您的業務邏輯。

+0

謝謝,但當我使用'CascadeType.REMOVE'時,我仍然得到相同的錯誤。 – kamaci

1

你需要確保沒有CarGroups有你想在其設置的汽車刪除汽車:

public void deleteCar(Car car) { 
    for (CarGroup group : car.getCarGroups()) { 
     group.getCars().remove(car); 
    } 
    session.delete(car); 
} 
+0

感謝您的回答。但是,如果我更改Cascade類型或將多對多關係變爲多對一和一對多關係,我可以這樣做嗎? – kamaci

+0

級聯,AFIK,沒有。有兩個協會:是的。但我不會。這會讓所有事情變得更加複雜。 –