@OnDelete Hibernate注释不会为MySql生成ON DELETE CASCADE

时间:2017-01-04 14:11:10

标签: mysql hibernate spring-boot spring-data jpa-2.1

我有两个具有单向关系的父实体和子实体

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

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

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

在我已配置的application.properties文件中

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

但是当我运行应用程序时,会创建以下语句

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

因此应该没有ON CASCADE DELETE。每次运行应用程序时都会创建表,我检查了方法

org.hibernate.dialect.MySQL5InnoDBDialect#supportsCascadeDelete()

真的被称为(它)。我使用的是spring-boot-parent版本1.4.3,它使用了Hibernate 5.11。有任何想法吗?顺便说一下,我不想使用双向关系。

修改 感谢@AlanHay,我发现我省略了一个重要的部分。实际上涉及第三类

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;
}

和幼儿园的孩子看起来真的像这样

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;
}

这就是问题发生的原因。如果将MapKeyJoinColumn批注中的“parent_id”更改为Child中不存在的内容,例如列“map_id”将ON DELETE CASCADE添加到Child中的外键parent_id。如果参数是Child的列“parent_id”,则不会追加ON DELETE CASCADE部分。不幸的是,我的原因尚不清楚。更改参数是没有选项的,因为我想使用现有链接到子对象的父级。

2 个答案:

答案 0 :(得分:2)

也许有点晚了,但因为它是搜索'hibernate ondelete generate cascade'时的热门帖子之一:

出于某种原因,将@OnDelete放在Mysql的ManyToOne端并不适用于我,但它适用于OneToMany端。所以,如果你运气不好,可以试试另一方。

答案 1 :(得分:0)

在我的情况下,我还必须将@OnDelete放在OneToMany一侧,此外,我还必须更改JpaVendorAdapter bean方法。它返回的适配器必须设置为org.hibernate.dialect.MySQL5InnoDBDialect,如下所示:

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