Kam*_*mil 4 java sql hibernate
假设我们有双向OneToOne关系。\n有User和Address实体。User有很多Addresses。
CREATE SEQUENCE IF NOT EXISTS hibernate_sequence;\nCREATE TABLE users (\n id BIGINT PRIMARY KEY\n);\n\nCREATE TABLE addresses (\n id BIGINT PRIMARY KEY,\n user_id BIGINT NOT NULL UNIQUE CONSTRAINT fk_addresses_user_id REFERENCES users(id) ON DELETE CASCADE,\n);\nRun Code Online (Sandbox Code Playgroud)\n\n和
\n\n@Table(name = "users")\npublic class User {\n\n @Id\n @GeneratedValue(strategy = GenerationType.SEQUENCE)\n private Long id;\n\n //mappings\n private Address address;\n}\n\n@Table(name = "addresses")\npublic class Address {\n\n @Id\n @GeneratedValue(strategy = GenerationType.SEQUENCE)\n private Long id;\n\n //mapings\n private User user;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n我用OneToOne的是一个例子,但问题是关于一般关系的,所以正确的方法也是有效的ManyToMany。
TL;DR - 问题是关于mappedBy<->relation owner<->cascades<->managing other side in setters一般使用
User或Address) / (Owner 或 Inverse)?\n\nAddress应该有mappedByPost(User在我的示例中)已映射到PostDetails(Address在我的示例中)User拥有关系,因此Address应该有mappedBy(CustomerRecord在Java文档)Phone(Person在我的示例中)已mappedBy到PhoneDetails(Address)User或Address)/(mappedBy 或反面) ?@OneToOne(cascade = {CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH})public void addAddress(Address address) {\n if (address != null) {\n address.addUser(this);\n }\n this.addresses.add(address);\n}\n\npublic void removeAddress(Address address) {\n if (address != null) {\n address.removeUser(this);\n }\n this.addresses.remove(address);\n}\n\npublic Set<Address> getAddresses() {\n return Collections.unmodifiableSet(this.addresses);\n}\nRun Code Online (Sandbox Code Playgroud)\n\n(User或Address) / (mappedBy 或反面)?
User在我的示例中,父级管理的关系)此外 - 看看这两个链接:
\n\n先感谢您
\n\n附言。我的问题的先前版本用作OneToMany示例,但因为逆 -ManyToOne没有映射,所以我将其更改为OneToOne更好地显示问题
在关系数据库系统中,表关系分为三种类型:
因此,one-to-many表关系如下所示:
请注意,该关系基于post_id子post_comment表中的外键列。
因此,在管理表关系时,外键列是唯一的事实来源one-to-many。
现在,让我们采用一个双向 JPA 实体关系来映射one-to-many我们之前看到的表关系:
如果您看一下上图,您会发现有两种方法可以管理这种关系。
在Post实体中,您拥有以下comments集合:
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
Run Code Online (Sandbox Code Playgroud)
并且,在 中PostComment,post关联映射如下:
@ManyToOne(
fetch = FetchType.LAZY
)
@JoinColumn(name = "post_id")
private Post post;
Run Code Online (Sandbox Code Playgroud)
因此,您有两个可以更改实体关联的方面:
comments,新post_comment行应post通过其post_id列与父实体关联。post的属性PostComment,该post_id列也应该更新。由于有两种方法来表示外键列,因此在将关联状态更改转换为其等效的外键列值修改时,您必须定义哪种方法是真实来源。
该mappedBy属性告诉@ManyToOne一侧负责管理外键列,并且该集合仅用于获取子实体并将父实体状态更改级联到子实体(例如,删除父实体也应该删除子实体)。
它被称为反面,因为它引用管理此表关系的子实体属性。
现在,即使您定义了mappedBy属性并且子端@ManyToOne关联管理外键列,您仍然需要同步双向关联的两侧。
最好的方法是添加这两个实用方法:
public void addComment(PostComment comment) {
comments.add(comment);
comment.setPost(this);
}
public void removeComment(PostComment comment) {
comments.remove(comment);
comment.setPost(null);
}
Run Code Online (Sandbox Code Playgroud)
和addComment方法removeComment确保双方同步。因此,如果我们添加一个子实体,则子实体需要指向父实体,并且父实体应该将子实体包含在子集合中。
| 归档时间: |
|
| 查看次数: |
5642 次 |
| 最近记录: |