2016-10-06 126 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