Hibernate DataIntegrityViolationException Нарушение внешнего ключа не позволяет удалить - PullRequest
0 голосов
/ 10 ноября 2011

У меня такие отношения.Существует таблица 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 ]

1 голос
/ 10 ноября 2011

Вы должны убедиться, что ни одна из CarGroups не имеет машины, которую вы хотите удалить в своем наборе машин:

public void deleteCar(Car car) {
    for (CarGroup group : car.getCarGroups()) {
        group.getCars().remove(car);
    }
    session.delete(car);
}
1 голос
/ 10 ноября 2011

Вы не можете удалить автомобиль, потому что на строку в таблице cargroup_car есть ссылка на нее. Поэтому вам нужно удалить строку cargroup_car перед удалением машины.

0 голосов
/ 10 ноября 2011

Просто предположение: попробуйте добавить CascadeType.REMOVE

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

Или есть другой вариант: вы можете изменить ограничение внешнего ключа в базе данных для каскадного удаления из автомобиля в группу, хотя это может быть опасно, это зависит от вашей бизнес-логики.

...