JPA - 删除时的ConstraintViolationException

时间:2016-02-20 18:14:34

标签: java mysql hibernate spring-mvc jpa

我搜索了互联网,尝试了很多方法,但在移除过程中我仍然遇到问题。请给我任何指示,因为我想了解我做错了什么。

我有几个实体,但简而言之:

public class PetOwner extends User {
    private String address;
    private String telefon;

    @OneToMany(cascade={CascadeType.REMOVE})
    private List<Appointment> appointments;
}


public class Appointment {
    @Id
    @GeneratedValue
    private long id;

    @ManyToOne(cascade={CascadeType.PERSIST})
    @JoinColumn(name = "owner_id")
    private PetOwner petOwner;
}

当我尝试使用此方法删除约会(JpaRepository)

@Transactional
    public void delete(Appointment appointment){
        appointmentRepository.delete(appointment);
    }

Spring抛出异常:

MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails

在Appointment.class中设置了唯一方法

@ManyToOne(cascade={CascadeType.ALL})
    @JoinColumn(name = "owner_id")
    private PetOwner petOwner;

但是除了会议之外还会删除PetOwner。请告知如何处理。

2 个答案:

答案 0 :(得分:1)

首先,你应该只在@OneToMany级联。其次,错误似乎来自DB,而不是来自JPA。您的外键似乎设置错误。

请参阅FK的这个答案:FK restriction

设置您要做的事情的正确方法是:

 @OneToMany(cascade={CascadeType.DELETE},mappedBy = "petOwner")
 private List<Appointment> appointments;

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name = "owner_id")
private PetOwner petOwner;

答案 1 :(得分:1)

如果没有参与有关创建反映属性(而不是自然)的层次结构的争论,可以在此处使用两种方法。

首先,你可以更好地写下你的人际关系。我不知道您选择的JPA实现是什么,但有时他们搞砸了创建不必要的链表的表格。所以,比抱歉更安全:

在PetOwner上,使用:

@OneToMany(cascade={CascadeType.REMOVE}, mappedBy="petOwner")
private List<Appointment> appointments;

第二个方法是明确说明您的所有者在删除之前没有预约,所以:

@Transactional
public void delete(Appointment appointment){
    appointment.getPetOwner().getAppointments().remove(appointment);
    appointmentRepository.delete(appointment);
}

这个非常糟糕,因为当所有者需要多次约会时,你可能会遇到巨大的性能问题。