2016-10-06 93 views
0

我正在用hibernate挣扎。我想删除对象,但我得到的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; 

所以我' m试图删除meetup实体,但通过这样做我不想删除coresponding Location实体。现在,当我试图删除聚会实体(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 

的问题可以通过改变级联型来解决,以“ALL”在聚会类映射,但是那显然我的位置实体也将被删除。这是我不想发生的事情。那么我怎么能删除meetup实体而不删除位置实体呢?

+0

请转储您的完整例外文本,以便其他人可以更好地为您提供帮助1 –

+0

如果您想删除Meetup,您需要先删除所有引用它的Match实体。这可以通过在“Meetup”中添加后向引用并向其添加相应的级联来完成。 - 注意'Location'不是你问题的一部分:“_PUBLIC.MATCH_ FOREIGN KEY(MEETUP_ID)REFERENCES PUBLIC.MEETUP(ID)”。 – Thomas

+0

是的我已经注意到,但是我必须删除匹配,并通过这样做来限制另一个表(由于ManyToMany关系而发生),所以我必须删除匹配项,然后我必须删除匹配项,最后我可以删除聚会。哪一点太糟糕了,因为我只是为了消除聚会而抹去了整个数据库。我的设计是否因此而吸?这个案例是两个用户得到了一场比赛,他们决定在X地点开会,但他们改变了想要去Y地点的想法,他们仍然喜欢彼此(比赛应该留下):D – filemonczyk

回答

1

所有你只需要做的是确保你处理去除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); 

鉴于你的模型,也没有必要与级联操作捏造的这个用例。

+0

所以你说有没有需要使用级联操作?我每次都会推荐它,这样我就可以用更少的努力获得最新的数据库 – filemonczyk