Hibernate 和 JPA“mappedBy”与关系和级联的所有者

2023-12-27

背景

假设我们有双向OneToOne关系。 有User and Address实体。User有很多Addresses.

CREATE SEQUENCE IF NOT EXISTS hibernate_sequence;
CREATE TABLE users (
  id BIGINT PRIMARY KEY
);

CREATE TABLE addresses (
  id BIGINT PRIMARY KEY,
  user_id BIGINT NOT NULL UNIQUE CONSTRAINT fk_addresses_user_id REFERENCES users(id) ON DELETE CASCADE,
);

and

@Table(name = "users")
public class User {

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

  //mappings
  private Address address;
}

@Table(name = "addresses")
public class Address {

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

  //mapings
  private User user;
}

免责声明:

我在用着OneToOne举个例子,但问题是关于一般关系,所以正确的方法适用于ManyToMany以及。

TL;DR - 问题是关于使用mappedBy<->relation owner<->cascades<->managing other side in setters一般来说

问题:

  1. 数据库中的地址表表中应该有user_id吧?那么谁是关系的所有者呢?
  2. In entities: which one should have mappedBy - (User or Address) / (Owner or Inverse)?
    • 这个链接:https://coderanch.com/t/595728/databases/Newbie-Hibernate-OneToMany-owning-side https://coderanch.com/t/595728/databases/Newbie-Hibernate-OneToMany-owning-side状态:“请注意,mappedBy 自动使关系成为反向或非拥有方。”所以Address应该有映射者
    • 在此链接中:https://vladmihalcea.com/the-best-way-to-map-a-onetoone-relationship-with-jpa-and-hibernate/ https://vladmihalcea.com/the-best-way-to-map-a-onetoone-relationship-with-jpa-and-hibernate/ Post (User在我的示例中)已映射到PostDetails (Address在我的例子中)
    • Java文档:https://docs.oracle.com/javaee/7/api/javax/persistence/OneToOne.html#mappedBy() https://docs.oracle.com/javaee/7/api/javax/persistence/OneToOne.html#mappedBy()说“拥有关系的领域”所以User拥有该关系,因此Address应该有mappedBy (CustomerRecord在 JavaDoc 中)
    • 但是休眠文档:http://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#associations-one-to-one-bidirection http://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#associations-one-to-one-bidirectional家长Phone (Person在我的例子中)已经被映射到PhoneDetails (Address)
  3. 在哪一边(User or Address) / (mappedBy 或反面)@OneToOne(cascade = {CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH})应该放置?
  4. 最后一个问题:哪个实体应该像这样管理关系:
public void addAddress(Address address) {
  if (address != null) {
    address.addUser(this);
  }
  this.addresses.add(address);
}

public void removeAddress(Address address) {
  if (address != null) {
    address.removeUser(this);
  }
  this.addresses.remove(address);
}

public Set<Address> getAddresses() {
  return Collections.unmodifiableSet(this.addresses);
}

the (User or Address) / (mappedBy 或反面)?

  • 这个链接:https://vladmihalcea.com/the-best-way-to-map-a-onetomany-association-with-jpa-and-hibernate/ https://vladmihalcea.com/the-best-way-to-map-a-onetomany-association-with-jpa-and-hibernate/显示了上面列出的方法(其中父级,User在我的示例中,管理关系)
  • 但在这儿:https://www.quora.com/What-is-the- Purpose-of-mapped-by-element-in-OneToMany-annotation-in-Hibernate https://www.quora.com/What-is-the-purpose-of-mapped-by-element-in-OneToMany-annotation-in-HibernateVlad 说:“如果外键所在的子方控制关联,这总是一个好的做法”,所以地址应该“控制关系”(完全相反)?

此外 - 查看这两个链接:

  • https://docs.oracle.com/javaee/7/api/javax/persistence/OneToOne.html https://docs.oracle.com/javaee/7/api/javax/persistence/OneToOne.html- 这里 CustomerRecord 已被映射
  • https://docs.oracle.com/javaee/7/api/javax/persistence/OneToMany.html https://docs.oracle.com/javaee/7/api/javax/persistence/OneToMany.html- 但这里客户已经映射了!

先感谢您

附言。我的问题的先前版本正在使用OneToMany作为一个例子,但因为相反 -ManyToOne没有映射我将其更改为OneToOne哪个更能说明问题


表关系与实体关系

在关系数据库系统中,表关系分为三种类型:

  • 一对多(通过外键列)
  • 一对一(通过共享主键)
  • 多对多(通过带有两个外键引用两个单独父表的链接表)

So, a one-to-many表关系如下所示:

请注意,该关系基于post_id子项中的外键列post_comment table.

因此,在管理数据时,外键列是唯一的事实来源one-to-many表关系。

现在,我们采用一个双向 JPA 实体关系来映射one-to-many我们之前看到的表关系:

如果您看一下上图,您会发现有两种方法可以管理这种关系。

In the Post实体,你有comments收藏:

@OneToMany(
    mappedBy = "post",
    cascade = CascadeType.ALL,
    orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();

并且,在PostComment, the post关联映射如下:

@ManyToOne(
    fetch = FetchType.LAZY
)
@JoinColumn(name = "post_id")
private Post post;

因此,您有两个可以更改实体关联的方面:

  • 通过在comments儿童收藏,新post_comment行应该与父行相关联post实体通过其post_id column.
  • 通过设置post的财产PostComment实体,即post_id列也应该更新。

由于有两种方法来表示外键列,因此在将关联状态更改转换为其等效的外键列值修改时,您必须定义哪种方法是真实来源。

MappedBy(又称反面)

The mappedBy属性告诉我们@ManyToOneside 负责管理外键列,并且该集合仅用于获取子实体并将父实体状态更改级联到子实体(例如,删除父实体也应该删除子实体)。

它被称为反面因为它引用管理此表关系的子实体属性。

同步双向关联的双方

现在,即使您定义了mappedBy属性和子端@ManyToOne关联管理外键列,您仍然需要同步双向关联的双方。

最好的方法是添加这两个实用方法:

public void addComment(PostComment comment) {
    comments.add(comment);
    comment.setPost(this);
}

public void removeComment(PostComment comment) {
    comments.remove(comment);
    comment.setPost(null);
}

The addComment https://vladmihalcea.com/jpa-hibernate-synchronize-bidirectional-entity-associations/ and removeComment https://vladmihalcea.com/jpa-hibernate-synchronize-bidirectional-entity-associations/方法确保双方同步。因此,如果我们添加一个子实体,则子实体需要指向父实体,并且父实体应该将子实体包含在子集合中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Hibernate 和 JPA“mappedBy”与关系和级联的所有者 的相关文章

随机推荐

  • WPF - 使用样式为每个 TreeViewItem 根节点设置不同的 ToggleButton 图像

    我不熟悉在 WPF 中使用样式 资源和模板 我需要做的是将 TreeView 中的 ToggleButton 重写为图像 每个 TreeViewItem 根节点使用不同的图像 例如 我想要一张汽车图像作为 汽车 节点 一张飞机图像作为 飞机
  • 在 url 中传递一个 php 变量的最简单方法[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我已经检查了有关如何在 url 中传
  • 无法将 lambda 表达式转换为“string”类型,因为它不是委托类型 [重复]

    这个问题在这里已经有答案了 我正在使用 LINQ lambda 表达式 如下所示 int Value 1 qryContent objContentLine using Entities db new Entities objContent
  • 为什么使用隐式转换时会出现无限循环?

    Context object Fibonacci final val Threshold 30 def fibonacci n Int implicit implementation Fibonacci Int implementation
  • python:从自定义概率函数中随机采样[重复]

    这个问题在这里已经有答案了 我有一个带有概率密度函数的分段四次分布 p x c x a 2 if 0 x
  • ASP.NET MVC - 如何在强类型文本区域中设置默认值?

    我试图让 TextArea 具有默认值 这可以正常工作在TextBoxFor但不适用于TextAreaFor 我错过了一些非常明显的东西吗 您可以在创建模型时在控制器操作中指定 Description 属性的值 并将该模型传递给视图 pub
  • iSeries AS400 ODBC 连接的文件 DSN

    如何使用 iSeries ODBC 驱动程序创建文件 dsn 以连接到 AS400 系统 iSeries ODBC 驱动程序允许配置许多设置 在哪里可以找到可在文件 DSN 中设置的所有属性的列表 Driver iSeries Access
  • HTML 文本框无法输入内容

    我需要帮助 我页面中的表单如下所示 但是当我单击文本框时 光标不会出现并且无法输入
  • 使用“file.copy”通过网络复制文件比“system(mv ...)”慢得多

    当我通过公司网络访问文件时 R 变得非常缓慢 我遇到了一些问题 所以我回去做了一些测试 我惊讶地发现 Rfile copy 命令是much比使用等效文件复制慢system mv 这是一个已知问题还是我在这里做错了什么 这是我的测试 我有三个
  • Clang 构建非常慢并且中途挂起

    我正在开始编写自己的 clang 工具 这些是我到目前为止所遵循的步骤 查看 llvm 7 0 发行版 查看 clang 7 0 版本 建造 使用带有以下标志的 ninja 构建 clang 和 llvm 没有这些标志就一直挂在我身上 DL
  • 产量有限制的子组合

    我正在使用 python 3 我正在使用的函数如下 def sub combinations segment if len segment 1 yield segment else for j in sub combinations seg
  • 在 Swift 包管理器中添加对二进制目标的依赖项

    我想创建一个带有具有子依赖项的二进制目标的 Swift 包 由于二进制目标不支持开箱即用的子依赖项 因此我创建了一个包装器目标 该目标既依赖于二进制框架又依赖于所述的其他依赖项here https stackoverflow com a 6
  • 如何将 NSNumber 转换为 NSString

    所以我有一个NSArray myArray 与NSNumbers and NSStrings 我需要它们在另一个UIView所以我就这样 void tableView UITableView tableView didSelectRowAt
  • 将div类中的信息提取到json对象(或数据框)

    对于表中的每一行页面 我想单击 ID 例如 第 1 行的 ID 是 270516746 并将信息 每行没有相同的标题 提取 下载到某种形式的 python 对象中 最好是 json 对象 或数据框 json 可能更容易 我已经到了可以到达我
  • “CHOICE_MODE_MULTIPLE_MODAL”网格视图的最大可选数量

    我创建了一个 GridviewCHOICE MODE MULTIPLE MODAL在安卓中 一切都运转良好 但根据要求 我必须为可选项目设置限制 假设 gridview 的最大可选项目限制是 3 个项目 达到限制后 用户无法再选择并会显示一
  • 为 Windows CE 编译 Boost 1.47

    实际上有一些关于人们尝试为 Windows CE 构建 Boost 库的信息 但没有人报告成功 甚至没有给出这样做所需的步骤 对于两个最新版本 1 46 和 1 47 发行说明提到他们的测试编译器之一是 Visual C Windows M
  • 如何在Python中检查EOF? [复制]

    这个问题在这里已经有答案了 如何在 Python 中检查 EOF 我在代码中发现了一个错误 其中分隔符后的最后一个文本块未添加到返回列表中 或者也许有更好的方式来表达这个功能 这是我的代码 def get text blocks filen
  • JQuery 透视对话框覆盖

    有几个 JQuery 插件可以放置模式对话框并在对话框中显示 dom 元素 但我正在寻找一个对话框叠加层 它可以显示屏幕的某些部分 并且这些区域应该是可访问的 而其他元素应该被阻止 我已经整理了一个简单的插件来执行此操作 不确定您的要求范围
  • 在 matplotlib 中绘制 unix 时间戳

    我想用 python 的 matplotlib 模块制作一个通用值与时间图 我的时间是 unix 时间 但我希望它们以可读的格式显示在绘图的 x 轴上 我已阅读有关使用日期时间对象进行绘图的答案 但此方法似乎删除了小时 分钟 秒信息和全天的
  • Hibernate 和 JPA“mappedBy”与关系和级联的所有者

    背景 假设我们有双向OneToOne关系 有User and Address实体 User有很多Addresses CREATE SEQUENCE IF NOT EXISTS hibernate sequence CREATE TABLE