Проблемы с каскадным удалением в Hibernate - PullRequest
7 голосов
/ 15 мая 2011

Этот вопрос задавался много раз прежде, но я не видел удовлетворительного ответа с тех пор, поэтому я спрашиваю его снова.

Представьте себе следующую ситуацию:

public class User {
    ...

    @Cascade(value= {CascadeType.DELETE})
    @OneToMany(fetch = FetchType.LAZY)
    @JoinColumn(name="followerId")
    public List<LocationFollower> followedLocations;

    ...
}

public class LocationFollower {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id", nullable = false)
    public Long id;

    @ManyToOne
    @JoinColumn(name="locationId")
    public Location followedLocation;

    @ManyToOne
    @JoinColumn(name="followerId")
    public User follower;

    @Column(name = "followerSince")
    public Timestamp followerSince;
}

public class Location {
    ...

    @Cascade(value = {CascadeType.DELETE})
    @OneToMany(fetch= FetchType.LAZY)
    @JoinColumn(name="locationId")
    public List<LocationFollower> followers;

    ...
}

Все, что я хотел, это удалить пользователя.Логично предположить, что все связанные записи «подписчик», связывающие пользователя и местоположение, будут удалены.То же самое предположение должно оставаться в силе, если я удаляю запись Location.

На самом деле происходит то, что Hibernate пытается обновить (?!?) Таблицу, содержащую подписчиков, а также связанную сущность (User или Location)) был отправлен для удаления, пытается установить внешний ключ, например followerId со значением NULL.Это вызывает исключение и прерывает все последующие операции.

Я получаю ошибку: Произошел необработанный сбой на сервере.Не удалось выполнить пакетное обновление JDBC;SQL [обновить locationstofollowers set followerId = null, где followerId =?];ограничение [ноль];вложенное исключение - org.hibernate.exception.ConstraintViolationException: не удалось выполнить пакетное обновление JDBC

PS Я слышал, что был другой параметр каскада DELETE_ORPHAN.Это кажется устаревшим, и хотя я тоже пробовал, эффект был тот же.

Ответы [ 2 ]

1 голос
/ 15 мая 2011

Поскольку вы сделали двунаправленное отображение, вы должны удалить объект из обоих мест. Это должно работать:

user.followedLocations.remove(aLocation);
session.update(user);
session.delete(aLocation);
0 голосов
/ 12 сентября 2013

Вы должны установить @JoinColumn (name = "followerId", вставляемый = ложный, обновляемый = ложный)

...