删除实体时违反约束
Constraint violation when deleting entities
我正在与休眠作斗争。我正在尝试删除对象,但出现 sql 异常。
首先是我的映射:
@Entity
public class Meetup {
@Id
@GeneratedValue
@Column
private long id;
@Column(nullable = false)
private ZonedDateTime dateAndTime;
@ManyToOne(fetch = FetchType.EAGER,cascade=CascadeType.PERSIST)
private Location location;
///////////////////////
@Entity
public class Location {
@Id
@GeneratedValue
@Column
private long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private double longitude;
@Column(nullable = false)
private double latitude;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "location")
private List<Meetup> meetups;
////////////////////////////////////////////////
@Entity
public class Match {
@Id
@GeneratedValue
@Column
private long id;
@ManyToMany(fetch = FetchType.LAZY, cascade=CascadeType.ALL)
private List<User> users = new ArrayList<>();
@OneToOne(cascade=CascadeType.ALL)
@JoinColumn(name = "meetup_id")
private Meetup meetup;
所以我试图删除聚会实体,但这样做我不想删除对应的位置实体。现在,当我尝试删除聚会实体 (entityManager.remove) 时,我得到
constraint ["FKJRLUYUGNHRKYWSVSRE8VE9I9D: PUBLIC.MATCH FOREIGN KEY(MEETUP_ID) REFERENCES PUBLIC.MEETUP(ID) (1)"; SQL statement: delete from meetup where id=? [23503-192]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
在聚会 class 中将映射的级联类型更改为 "ALL" 可以解决问题,但显然我的 Location 实体也会被删除。这是我不想发生的事情。那么如何在不删除地点实体的情况下实现删除聚会实体呢?
您只需确保在事务范围内按如下方式处理 MeetUp
的删除:
// Get your meetup by identifier
final Meetup meetup = entityManager.find( Meetup.class, meetupId );
// cleanup the match associations with meetup
entityManager.createQuery( "FROM Match WHERE meetup = :meetup")
.setParameter( "meetup", meetup )
.getResultList()
.forEach( match -> { match.setMeetup( null ); } );
// remove meetup
entityManager.remove( meetup );
鉴于您的模型,没有必要为这个用例捏造级联操作。
我正在与休眠作斗争。我正在尝试删除对象,但出现 sql 异常。
首先是我的映射:
@Entity
public class Meetup {
@Id
@GeneratedValue
@Column
private long id;
@Column(nullable = false)
private ZonedDateTime dateAndTime;
@ManyToOne(fetch = FetchType.EAGER,cascade=CascadeType.PERSIST)
private Location location;
///////////////////////
@Entity
public class Location {
@Id
@GeneratedValue
@Column
private long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private double longitude;
@Column(nullable = false)
private double latitude;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "location")
private List<Meetup> meetups;
////////////////////////////////////////////////
@Entity
public class Match {
@Id
@GeneratedValue
@Column
private long id;
@ManyToMany(fetch = FetchType.LAZY, cascade=CascadeType.ALL)
private List<User> users = new ArrayList<>();
@OneToOne(cascade=CascadeType.ALL)
@JoinColumn(name = "meetup_id")
private Meetup meetup;
所以我试图删除聚会实体,但这样做我不想删除对应的位置实体。现在,当我尝试删除聚会实体 (entityManager.remove) 时,我得到
constraint ["FKJRLUYUGNHRKYWSVSRE8VE9I9D: PUBLIC.MATCH FOREIGN KEY(MEETUP_ID) REFERENCES PUBLIC.MEETUP(ID) (1)"; SQL statement: delete from meetup where id=? [23503-192]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
在聚会 class 中将映射的级联类型更改为 "ALL" 可以解决问题,但显然我的 Location 实体也会被删除。这是我不想发生的事情。那么如何在不删除地点实体的情况下实现删除聚会实体呢?
您只需确保在事务范围内按如下方式处理 MeetUp
的删除:
// Get your meetup by identifier
final Meetup meetup = entityManager.find( Meetup.class, meetupId );
// cleanup the match associations with meetup
entityManager.createQuery( "FROM Match WHERE meetup = :meetup")
.setParameter( "meetup", meetup )
.getResultList()
.forEach( match -> { match.setMeetup( null ); } );
// remove meetup
entityManager.remove( meetup );
鉴于您的模型,没有必要为这个用例捏造级联操作。