【问题标题】:Hibernate saving child entity without inserting parent休眠保存子实体而不插入父实体
【发布时间】:2017-08-28 15:15:57
【问题描述】:

我想插入一个新的子记录,其中父关系已经存在于数据库中,而不必先通过查询获取父项,然后再插入新的子项。

示例:我有一个产品实体,它有一个 ManyToOne 和一个现有的 Catalog 实体:

@NotNull
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "catalog_id",
  referencedColumnName = "id", foreignKey = @ForeignKey(name = "FK_product_catalog"))
private Catalog catalog;

我希望能够在目录中插入新产品,而无需先查询目录来填充新产品实体。

事实上,我在 restController 的 POST 中接收到一个 json,该 Json 包含产品属性和目录 ID。

这是 Json:

{
  "id":1,
  "attribute1":"value",
  "catalog":{"id":1}
}

一旦发生序列化,Product 实例就会正确形成,其中包含一个只有 id 字段值的 Catalog 实例。

我在插入时收到此消息:

尝试保存一个或多个具有不可为空的实体 与未保存的临时实体关联

我明白为什么我会收到这条消息,我也可以从数据库中获取目录行,但这意味着我每次插入子行时都必须查询所有父母,这在设计上毫无意义,因为我真的仅插入具有外键引用的行。

有人知道如何防止这种行为吗?

【问题讨论】:

    标签: hibernate spring-mvc


    【解决方案1】:

    您为什么不为 catalog_id 创建一个单独的属性并将@NotNull 约束放在那里而不是 Catalog 对象属性?

    【讨论】:

    • 我最初想让数据库 ddl 由 hibernate 生成,我仍在努力让它以这种方式工作。当我从数据库中选择产品时,我还希望能够急切地获取该目录。但是如果我插入一个产品,我只希望在产品行中插入 catalogId,而不需要为目录部分执行额外的选择。
    • 对我来说似乎是一个非常标准的功能。我想在选择时急切获取,但我只想插入产品实体,如果目录不存在,让数据库强制执行外键约束。
    • 我尝试了你的建议,它解决了问题。通过保持与 Catalog 的 ManyToOne 关系(使用 insert 和 update =false)并添加 catalog_id 字段,我现在可以通过仅具有父关系的 id 来仅插入产品实体。尽管如此,实体中存在重复项(同时具有 catalog.id 和 catalod_id 字段)可能会导致长期问题,但它比对插入进行多次无用选择要好。
    猜你喜欢
    • 2016-12-27
    • 2012-09-09
    • 2014-02-25
    • 2013-07-24
    • 1970-01-01
    • 1970-01-01
    • 2015-01-30
    • 1970-01-01
    相关资源
    最近更新 更多