如何在 JPA 中获取外键引用以具有“ON UPDATE CASCADE ON DELETE CASCADE”功能?

Posted

技术标签:

【中文标题】如何在 JPA 中获取外键引用以具有“ON UPDATE CASCADE ON DELETE CASCADE”功能?【英文标题】:How do I get a foreign key reference in JPA to have "ON UPDATE CASCADE ON DELETE CASCADE" functionality? 【发布时间】:2019-09-26 21:19:40 【问题描述】:

至少在过去的 6 个小时里,我一直在不停地胡闹,我就是不明白问题出在哪里。我在我的 SpringBoot 项目中设置了两个类(用户和项),两个类之间有如下双向关系:

@OneToMany 从用户到项目的关系(一个用户可以拥有多个项目) 从项目到用户的@ManyToOne 关系(每个项目只有一个用户)

这是我的用户类:

@Data
@Entity
@AllArgsConstructor
@Table(name="users")
public class User implements Serializable    

    @Id
    private @NotNull String id;
    private @NotNull String username;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.owner", cascade = CascadeType.ALL)
    private List<Item> ownedItems;

    ...

这是我的 Item 类(它使用复合主键):

@Data
@Entity
@AllArgsConstructor
@Table(name="items")
public class Item implements Serializable 


    @Data
    @Embeddable
    public static class PrimaryKey implements Serializable 

        private @NotNull String id;

        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(                
                name="user_id",
                referencedColumnName = "id",
                foreignKey = @ForeignKey(name = "FK_Item_UserID"),
                nullable = false,     // I have tried using these
                updatable = false,    // and excluding these and
                insertable = false    // that changes nothing
        )
        private @NotNull User owner;
    


    @EmbeddedId
    private @NotNull PrimaryKey pk;

    private @NotNull String name, item_condition, categories;
    private @NotNull LocalDateTime postDate;

问题是由 Hibernate 创建的表(由 SQL 查询“SHOW CREATE TABLE items”返​​回是这样的:

CREATE TABLE `items` (
  `id` varchar(255) NOT NULL,
  `categories` varchar(255) NOT NULL,
  `item_condition` varchar(255) NOT NULL,
  `name` varchar(255) NOT NULL,
  `post_date` datetime NOT NULL,
  `user_id` varchar(255) NOT NULL,
  PRIMARY KEY (`id`,`user_id`),
  KEY `FK_Item_UserID` (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

请注意,外键引用只是一个 KEY 而不是 FOREIGN KEY。下一个问题是它在更新或删除时没有做任何事情,这是一个大问题。 我希望此表的外键如下所示:

FOREIGN KEY ('user_id') REFERENCES Users('id') ON UPDATE CASCADE ON DELETE CASCADE

谁能向我解释如何实现这一目标以及为什么我所拥有的不起作用?

【问题讨论】:

MyISAM 不强制执行 FK 约束,您需要 ENGINE=Innodb。 你知道我会设置它吗?我会在哪里指定? @danblack 谢谢。我不知道你是谁,但你只是让我度过了我的一天,甚至可能是我的一周。对于遇到我同样问题的任何人,我都找到了后续问题 here 的答案。 【参考方案1】:

已解决

@danblack 告诉我我需要将引擎更改为“Innodb”。我通过将spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.mysql55Dialect 添加到我的application.properties 文件来做到这一点。

感谢@danblack!

【讨论】:

注意推荐 'hibernate.dialect.storage_engine=innodb' 的 cmets。如果您的查询使用 innodb 很慢,请确保在 mysql 中将 innodb_buffer_pool_size 设置为将在您的查询中保存活动数据的内容。欢迎来到 SO。

以上是关于如何在 JPA 中获取外键引用以具有“ON UPDATE CASCADE ON DELETE CASCADE”功能?的主要内容,如果未能解决你的问题,请参考以下文章

如何把单体式应用拆解成微服务?下

如何让jpa休眠创建具有多对一但没有外键的实体

如何从具有外键类型的jpa存储库返回选择查询

JPA 2 一对多 - JPA 如何推断列信息?

如何避免使用 JPA 在实体关系中违反外键约束

带有没有外键的数据库的 Spring JPA