jansolo
jansolo

Reputation: 419

@OnDelete Hibernate annotation does not generate ON DELETE CASCADE for MySql

I have two entities parent and child with a unidirectional relationship

class Parent {
    @Id
    @GeneratedValue(strategy= GenerationType.AUTO)
    private Long id;
}

and

class Child {
    @Id
    @GeneratedValue(strategy= GenerationType.AUTO)
    private Long id;

    @ManyToOne(optional = false)
    @JoinColumn(name = "parent_id")
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Parent parent;
}

In the application.properties file I have configured

spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.database-platform = org.hibernate.dialect.MySQL5InnoDBDialect

But when I run the application the following statement is created

...
alter table child add constraint FKi62eg01ijyk2kya7eil2gafmx foreign key (parent_id) references parent (id)
...

So there is no ON CASCADE DELETE as there should be. The tables are created each time I run the application and I checked if the method

org.hibernate.dialect.MySQL5InnoDBDialect#supportsCascadeDelete()

is really called (it is). I am using spring-boot-parent version 1.4.3, which uses Hibernate 5.11. Any ideas? I do not want to use a bi-directional relationship by the way.

Edit Thanks to @AlanHay I discovered that I omitted an important part. There actually is a third class involved

class Kindergarten {

    @Id
    @GeneratedValue(strategy= GenerationType.AUTO)
    private Long id;

    @OneToMany(mappedBy = "kindergarten", fetch = FetchType.EAGER)
    @MapKeyJoinColumn(name = "parent_id") // parent_id causes the problem!
    private Map<Parent, Child> children;
}

and Child with Kindergarten looks actually like this

class Child {

    @Id
    @GeneratedValue(strategy= GenerationType.AUTO)
    private Long id;

    @ManyToOne(optional = false)
    @JoinColumn(name = "parent_id")
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Parent parent;

    @ManyToOne
    @JoinColumn(name = "kindergarten_id")
    private Kindergarten kindergarten;
}

and that is why the problem occurs. If you change "parent_id" in the MapKeyJoinColumn annotation to something not existing in Child as a column e.g. "map_id" the ON DELETE CASCADE is added to the foreign key parent_id in Child. If the parameter is the Child's column "parent_id" the ON DELETE CASCADE part will not be appended. Unfortunately the reason for this is not yet clear to me. Changing the parameter is no option because I want to use the existing link to parent of the child object.

Upvotes: 3

Views: 5412

Answers (2)

Maurice
Maurice

Reputation: 7371

In my case I also had to place @OnDelete on the OneToMany side, next to that I also had to change the JpaVendorAdapter bean method. The adapter it returns must be set to org.hibernate.dialect.MySQL5InnoDBDialect like so:

adapter.setDatabasePlatform("org.hibernate.dialect.MySQL5InnoDBDialect");

Upvotes: 0

Markus Barthlen
Markus Barthlen

Reputation: 379

Maybe a little late, but since it is one of the top posts when searching for 'hibernate ondelete generate cascade':

For some reason putting @OnDelete on the ManyToOne side in Mysql did not work for me, but it worked on the OneToMany side. So if you are unlucky, try it on the other side.

Upvotes: 4

Related Questions