Search code examples
databasespring-bootjpaforeign-keysconstraints

How to Enforce Foreign Key Constraint on Delete with JPA and H2 Database


I have a Spring Boot application which has 2 tables in a h2 database: Computer and a Processor.

There is a unidirectional, many-to-one relationship between Computer and Processor such that many Computers can have one Processor.

@Entity
@Table(name = "Computer", schema = "CS")
public class Computer extends BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "computer_id")
    @Getter
    @Setter
    private long id;
    ...
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "processor_id")
    @OnDelete(action= OnDeleteAction.NO_ACTION)
    @Getter
    @Setter
    private Processor processor;
    ...
}

@Entity
@Table(name = "Processor", schema = "CS")
public class Processor extends BaseEntity {
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     @Column(name = "processor_id")
     @Getter@Setter
     private long id;
    ...
}

I want to enforce at a database level that when I try to delete a Processor that is referenced by at least one Computer, JPA does not allow the delete to be completed due to a foreign key constraint.

I understand that this functionality can be completed programmatically, such as finding all of the Computers associated with a certain Processor, however this seems like a code smell and it would be ideal to have JPA annotations take care of this for me, if it is possible.

Thank you!


Solution

  • Try with the @ForeignKey annotation, I haven't used it before but from the docs it should do what you want: https://docs.jboss.org/hibernate/jpa/2.1/api/javax/persistence/ForeignKey.html

    An alternative, use a the entity life cycle callbacks (see https://www.baeldung.com/jpa-entity-lifecycle-events). A @PreRemove method where you check if there is any entity depenent on the one you are deleting and throw a custom runtime exception... But the first approach should be enough