【问题标题】:MySQLIntegrityConstraintViolationException for Hibernate hsql delete. Cannot delete or update a parent row用于 Hibernate hsql 删除的 MySQLIntegrityConstraintViolationException。无法删除或更新父行
【发布时间】:2016-06-30 10:14:52
【问题描述】:

我有父 Filter 实体和一个方向 List<Ad>ads 作为具有@OneToManyrelation 的孩子。我尝试使用 Hibernate hql 查询删除超过一周的广告,但得到:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:无法删除或更新父行:外键约束失败(gecars.filters_ads,约束FK_gcri6h0918u8o2ybd6yfquk79外键(ads_id)参考@ 987654330@(id))

用户:

@Entity
@Table(name="users")
public class User {
 ...
 @OneToMany(fetch = FetchType.LAZY, cascade=CascadeType.ALL, mappedBy="user") 
 @OrderBy("id")
 private Set<Filter> filters = new HashSet<Filter>(0);
 ...

过滤器:

@Entity
@Table(name="filters")
public class Filter {
  ...
  // I also tried use @OneToMany(CascadeType.REMOVE, orphanremoval=true)
  // or @OneToMany(cascade=CascadeType.ALL,orphanRemoval=true)
  @OneToMany 
  private Set<Ad> ads; 
  ...

广告:

@Entity
@Table(name="ads")
public class Ad {
 ...
 private Date insertTime = new Date();
 ...

DAO删除方法:

public void deleteOldAds(Date date){
    String hql = "delete from Ad where insertTime < :date";
    session.createQuery(hql).setParameter("date",  date).executeUpdate();
}

【问题讨论】:

标签: java mysql hibernate


【解决方案1】:

问题的原因是如果@OneToMany关联方是关系的所有者,则使用了连接表。

要指定ads 表中的连接列(外键)用于关联而不是单独的连接表,只需将关联映射到@JoinColumn

@OneToMany
@JoinColumn 
private Set<Ad> ads; 

【讨论】:

    【解决方案2】:

    这是因为 Hibernate 不会从关系中删除实体 Ads

    因此,您需要在删除之前将自己 Ad 从关系中删除。

    或者您可以使用@OneToManymappedBy 它不会创建额外的表filters_ads 因为关系不会创建约束。

    【讨论】:

    • 因此,如果我决定在我的情况下使用@ManyToMany 关系,那么我应该首先选择所有过滤器,然后对它们进行 foreach 并检查广告插入时间,然后将其从过滤器实体中的广告列表中删除?
    • 这样的。但是您只能选择那些需要的过滤器,这些过滤器具有带有时间 的广告
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-15
    相关资源
    最近更新 更多