外键违反的Hibernate DataIntegrityViolationException不允许DELETE

时间:2011-11-09 21:01:55

标签: java hibernate foreign-keys data-integrity

我有这样的关系。有一个Car表和CarGroup表。汽车组表在它里面拿着汽车。我想要的是:当汽车被拆除时,如果它在汽车组内,它应该像往常一样从那里拆除。我在我的项目中使用Spring和Hibernate(我有一个PostgreSQL数据库)。当我想要拆除汽车时,我得到了这个错误:

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;

我得到的错误如下:

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".

CarGroup班的代码部分:

 @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端数据库设置(级联类型或将多个更改为多个到多个,一对多等)?

PS:我没有编写Java端代码。如果你解释一下,欢迎你。

3 个答案:

答案 0 :(得分:1)

您无法删除汽车,因为cargroup_car表中的行有对它的引用。因此,您需要在删除汽车之前删除cargroup_car行。

答案 1 :(得分:1)

您需要确保没有任何CarGroups拥有您要在其汽车组中删除的汽车:

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

答案 2 :(得分:0)

猜猜:尝试添加CascadeType.REMOVE

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

或者还有另一种选择:您可以更改数据库中的外键约束,以便将删除从汽车级联到汽车组,尽管这样做可能很危险,但这取决于您的业务逻辑。