@OnDelete Hibernate annotation does not generate O

2020-07-27 05:10发布

问题:

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.

回答1:

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.