Нарушение ограничений каскада Hibernate

У меня есть 2 объекта.

@javax.persistence.Entity
@Table(name="cities")
public class City  {

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    @Column(name="id")

    private long id;


    @Basic
    @Column(name = "name")
    private String name;

    @ManyToOne(cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
    @JoinColumn(name = "country", nullable = false)
    private Country country = null;
    ... //getters, setters
}

И второе - для страны

@Entity
@Table(name="countries")
public class Country   {

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    @Column(name="id")

    private long id;

    @Basic
    @Column(name = "name")
    private String name;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "country")
    @Fetch(value = FetchMode.SUBSELECT)
    private List<City> cities = new BlockingArrayQueue<>();
    ... //getters, setters
}

Мой тестовый код:

    Country country = new Country();
    country.setName("USA");

    countryDAO.add(country); //save country


    City city = new City();
    city.setName("New York");
    city.setCountry(country);

    cityDAO.add(city); //save city
    countryDAO.delete(country); //delete country

Я ожидал, что delete () удалит cascade из города, но я получаю исключение:

Referential integrity constraint violation: "FKTKJBA4WE2I3SH33J3IJK0M60N: PUBLIC.CITIES FOREIGN KEY(COUNTRY) REFERENCES PUBLIC.COUNTRIES(ID) (1)";

Я решил это, переписав метод City :: setCountry ():

public void setCountry(Country country) {
    if(this.country != null) this.country.getCities().remove(this); //delete from old country
    this.country = country;
    if(!country.getCities().contains(this)) country.getCities().add(this); //add to the new country
}

Почему спящий режим не может сделать это автоматически? Почему он не создает внешний ключ для City.Country с ON DELETE CASCADE ? Есть ли способ его правильно настроить?

java,hibernate,jpa,

0

Ответов: 1


2

Создание ограничения с помощью каскада - это функция, зависящая от базы данных. В качестве альтернативы вы можете добавить orphanRemoval = trueк своей @OneToManyаннотации, поэтому, когда вы звоните EntityManager.deleteв страну, она сначала удалит дочерние объекты для вас.

Java, спящий режим, JPA,
Похожие вопросы