【问题标题】:Hibernate cascade references constraint violationHibernate 级联引用约束冲突
【发布时间】:2016-10-15 20:53:36
【问题描述】:

我有 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
}

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

【问题讨论】:

    标签: java hibernate jpa


    【解决方案1】:

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

    【讨论】:

    • 所以,我发现添加 @OnDelete(action =OnDeleteAction.CASCADE) 解决了问题
    猜你喜欢
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-13
    • 2011-01-31
    • 1970-01-01
    相关资源
    最近更新 更多