【发布时间】:2017-09-26 09:44:03
【问题描述】:
我正在寻找一种方法来模拟 Hibernate 中同一类的两个或多个对象之间的关系。例如:我想创建一个我想模拟人与人之间关系的情况。在数据库中,我有两个表:
人:
- 身份证
- 姓名
关系:
- 父 ID
- 孩子身份证
我尝试在 Hibernate 中将其建模为 Person 有两个 ManyToMany 关系(Getter/Setter 注释是 Lombok):
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "persons")
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long Id
@Column(name="name")
private String name;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(
name = "relations",
joinColumns = {@JoinColumn(name = "parent_id", nullable = false)},
inverseJoinColumns = {@JoinColumn(name = "child_id", nullable = false)}
)
private Set<Person> children = new HashSet<>();
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(
name = "relations",
joinColumns = {@JoinColumn(name = "child_id", nullable = false)},
inverseJoinColumns = {@JoinColumn(name = "parent_id", nullable = false)}
)
private Set<Person> parents = new HashSet<>();
}
这给了我以下问题:
- 当获取类型为“LAZY”时,Hibernate 抱怨在调用 person.getChildren() 或 person.getParents() 时没有会话
- 对于获取类型“EAGER”,Hibernate 会为集合返回 null,这会在尝试添加子级或父级时导致空指针。我担心的另一件事是可能的无休止的递归渴望获取。
为了解决这个问题,我尝试将 Relation 建模为一个类,这样我就可以在 PersonRepository 中使用 JPA 查询来查找孩子和父母,而不必弄乱 ManyToMany 的复杂性:
public interface PersonRepository extends JpaRepository<Person, Long> {
@Query(
"select p from Person p join Relation r on p.id = r.childId where r.childId = :childId"
)
List<Person> findParents(Long childId);
}
这导致 Hibernate 抱怨 Relation 没有 @Id 字段。我不想添加,因为数据库中的关系表应该对关系进行建模,并且没有自己的 id。
当尝试在线搜索 Hibernate 中的类似结构时,我通常会在 the documentation 中找到经典的多对多示例,以及像 this one 这样的问题,其中两个不同类之间存在关系同一类的两个对象之间的关系。
我正在寻找一种方法来模拟 Hibernate 中同一类的两个或多个对象之间的关系。我希望能够延迟获取关系,或者出于性能原因之后获取它们。
如果关系表可以有一个额外的字段“type”来指示人(孩子、父母、侄子、朋友)之间的关系类型,那就太好了,这样就可以为新的关系类型留出空间,而无需太多改变数据库和代码。
【问题讨论】:
-
当涉及到使用链接表中的类型字段时,也许我在这里的回答会有所帮助:stackoverflow.com/questions/41732211/…
-
谢谢,但这映射了两个不同类之间的多对多关系。我正在尝试将 Persons 映射到 Persons。
标签: java hibernate many-to-many