我有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创建外键?有没有办法正确配置它?
答案 0 :(得分:2)
使用cascade创建约束是一种依赖于数据库的功能。作为替代方案,您可以在orphanRemoval = true
注释中添加@OneToMany
,因此当您使用国家/地区致电EntityManager.delete
时,它会首先删除它的子实体。