0
votes

How can I fix foreign key constraint violation when using Spring Data @OneToMany relationship with @JoinTable?

Models:

@Entity
@Data
public class Email {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "email_seq")
    @SequenceGenerator(name = "email_seq", sequenceName = "email_seq")
    private Long id;

    @NotNull
    private String title;

    @OneToMany
    @JoinTable(
            name = "email_attachment",
            joinColumns = @JoinColumn(name = "EMAIL_ID"),
            inverseJoinColumns = @JoinColumn(name = "ATTACHMENT_ID")
    )
    private List<Attachment> attachments;

    ...
}

@Entity
@Data
public class Attachment {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "attachment_generator")
    @SequenceGenerator(name = "attachment_generator", sequenceName = "attachment_seq")
    private Long id;

    ...
}

When I try to delete Attachment like this:

attachmentRepository.delete(id)

it throws following error:

ERROR: update or delete on table "attachment" violates foreign key constraint "email_attachment_attachment_id_fkey" on table "email_attachment" Details: Key (id)=(6) is still referenced from table "email_attachment".

4
You will also need to add cascadetype with @OneToMany annotation. - priteshbaviskar
As @22kar said, have a look at the JavaDoc for cascade types - Draken
Adding OneToMany(cascade = CascadeType.REMOVE) doesn't help. - Ziem
If deleting the "N" side of a 1-N unidir you first need to remove it from any relations that point to it ... i.e remove it from the Collection in Email - user3973283
@BillyFrost that was my plan B. Isn't it possible to do it automagically? - Ziem

4 Answers

0
votes

You need to create the relation in Attachment too with @ManyToOne.

Attachment.java

@Entity
@Data
public class Attachment {
    // ...

    @ManyToOne(mappedBy = "attachments")
    private Email email;

    // ...
}
0
votes

you can use the javax.persistence.CascadeType in JPA that will remove the corresponding entries from the parent table like that

@Entity
class Employee {

    @ManyToOne(cascade=CascadeType.REMOVE)
    private Address address;

}
0
votes

Option is to first delete email before deleting attachment object.

0
votes

Another choice would be to manually remove the attachment from the email. This would also cause the row in the join table to be deleted. If you combine this with orphanRemoval=true, the attachment will be deleted automatically.