我有3个Java
Hibernate
实体。与EntityUser
进行单向oneToMany
交互Filter
。Filter
实体与实体具有单向manyToOne
关系Model
。我只想删除Filter
实体,但要获取MySQLIntegrityConstraintViolationException
。
无法删除或更新父行:外键约束失败(
gecars
。users_filters
,CONSTRAINTFK_oymjo03tkarckpfjfmaak99lj
FOREIGN KEY(filters_id
)参考filters
(id
))
用户:
@Entity
@Table(name="users")
public class User {
...
//@OneToMany(fetch = FetchType.LAZY) // old
@OneToMany(fetch = FetchType.LAZY,cascade=CascadeType.ALL) //edited but exception still occurs
private Set<Filter> filters = new HashSet<Filter>(0);
筛选:
@Entity
@Table(name="filters")
public class Filter {
...
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "fk_model")
private Model model;
...
DAO类中的delete方法:
public void deleteFilter(int filterId){
String hql = "delete from Filter where id= :filterId";
session.createQuery(hql).setInteger("filterId", filterId).executeUpdate();
}
或session.delete
:
public void deleteFilter(int filterId){
try {
session.beginTransaction();
session.delete(getFilter(filterId));
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}
}
您正在使用联接表进行一对多关联。我假设您已经从映射自动生成了架构,因此您可能不知道这一点。这样,当您Filter
通过批量Hibernate DML语句删除s时,联接表中的记录将保留并导致违反外键约束。
最好的方法是在多个方面定义一个联接列:
@Entity
@Table(name="filters")
public class Filter {
@ManyToOne
@JoinColumn(name = "user")
private User user;
}
@Entity
@Table(name="users")
public class User {
@OneToMany(fetch = FetchType.LAZY, cascade=CascadeType.All, mappedBy="user")
private Set<Filter> filters = new HashSet<Filter>(0);
}
如果您不想使用双向关联,则可以在User
实体中定义连接列:
@Entity
@Table(name="users")
public class User {
@OneToMany(fetch = FetchType.LAZY, cascade=CascadeType.All)
@JoinColumn(name = "user")
private Set<Filter> filters = new HashSet<Filter>(0);
}
这样,联接列仍将在filters
表中,因此删除Filter
不会导致外键冲突。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句