Hibernate级联引用约束违规

时间:2016-10-15 20:53:36

标签: java hibernate jpa

我有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()已经删除了城市级联,但我得到了例外:

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
}

为什么hibernate不能自动完成?为什么不使用 ON DELETE CASCADE 为City.Country创建外键?有没有办法正确配置它?

1 个答案:

答案 0 :(得分:2)

使用cascade创建约束是一种依赖于数据库的功能。作为替代方案,您可以在orphanRemoval = true注释中添加@OneToMany,因此当您使用国家/地区致电EntityManager.delete时,它会首先删除它的子实体。