Hibernate:如何在更复杂的模型中设置关系(注释)?
Hibernate: how to set relations (annotations) in a more complex model?
我有以下简化模型:
Business - (1:n) - Assignment - (n:1) - Process
模型 classes 具有以下注释:
商业
@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(mappedBy = "business", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Assignment> assignments;
作业
通常会避免在此处创建单独的模型 class,因为业务和流程具有 n:m 关系。但是我需要给 Assigment 本身添加属性。
@ManyToOne
@JoinColumn(name = "business_id")
private Business business;
@ManyToOne
@JoinColumn(name = "process_id")
private Process process;
进程
@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(mappedBy = "process", cascade = CascadeType.ALL)
private List<Assignment> assignments;
要求
- 当一个业务或流程被删除时,我也想删除他的所有分配(但不是@OneToMany 方关系的合作伙伴)
- 删除分配时,我不想删除@OneToMany 双方(业务或流程)
提示
- 我尝试过使用
orphanRemoval = true
和不使用,但没有得到足够完整的解决方案
- 模型class继承自提供标识符的 MappedSuperClass
- 需要
@LazyCollection(LazyCollectionOption.FALSE)
,因为我在业务和流程中有多个 @OneToMany
关系,但此注释与此问题无关
- 我使用 H2 作为数据库,并且在与持久层交互时只使用 Spring 的 @Repository 接口,所以没有写一行 SQL
更新
不幸的是,我认为支持以下注释:
@OnDelete(action = OnDeleteAction.CASCADE)
并且 JUnit 测试批准了所需行为的正确工作,因此回答了我的问题。
@Test
public void test() {
// stores an Business object in db and returns the saved object
Business b = createBusiness();
// stores an Process object in db and returns the saved object
Process p = createProcess();
// stores Assignmnent object with both relations in db and returns the saved object
Assignment a = createAssignment(b, p);
assertThat(a).isNotNull();
// deletes Process object from db
processService.delete(p);
assertThat(processService.getById(p.getId())).isNull();
assertThat(assignmentService.getById(a.getId())).isNull();
assertThat(businessService.getById(b.getId())).isNotNull();
}
但事实并非如此。在我的 JavaFX 应用程序中,删除被记录下来,看起来它正在工作,但是当之后查询数据库时,实体仍然在 table 中,尽管在 JUnit 测试中它不是......
如果有人能对这个问题有所启发,我将不胜感激。
如果需要任何进一步的信息,我当然会提供。非常感谢您帮助我。
编辑
最后我解决了这个问题并通过以下设置获得了我想要的行为:
商业
@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(mappedBy = "business", orphanRemoval = true)
@OnDelete(action = OnDeleteAction.CASCADE)
private List<Assignment> assignments;
作业
@ManyToOne
@JoinColumn(name = "business_id")
private Business business;
@ManyToOne
@JoinColumn(name = "process_id")
private Process process;
进程
@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(mappedBy = "process", orphanRemoval = true)
@OnDelete(action = OnDeleteAction.CASCADE)
private List<Assignment> assignments;
请注意添加的注释@OnDelete(action = OnDeleteAction.CASCADE)
。这个提示来自 here。我在这里省略了 Hibernate 文档,因为它们(恕我直言)没有提供比链接的 SO post.
更多关于该功能的有用信息
更新:
还要考虑删除的 cascade
属性,这不是必需的,因为我正在使用休眠 @OnDelete
.
我有以下简化模型:
Business - (1:n) - Assignment - (n:1) - Process
模型 classes 具有以下注释:
商业
@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(mappedBy = "business", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Assignment> assignments;
作业
通常会避免在此处创建单独的模型 class,因为业务和流程具有 n:m 关系。但是我需要给 Assigment 本身添加属性。
@ManyToOne
@JoinColumn(name = "business_id")
private Business business;
@ManyToOne
@JoinColumn(name = "process_id")
private Process process;
进程
@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(mappedBy = "process", cascade = CascadeType.ALL)
private List<Assignment> assignments;
要求
- 当一个业务或流程被删除时,我也想删除他的所有分配(但不是@OneToMany 方关系的合作伙伴)
- 删除分配时,我不想删除@OneToMany 双方(业务或流程)
提示
- 我尝试过使用
orphanRemoval = true
和不使用,但没有得到足够完整的解决方案 - 模型class继承自提供标识符的 MappedSuperClass
- 需要
@LazyCollection(LazyCollectionOption.FALSE)
,因为我在业务和流程中有多个@OneToMany
关系,但此注释与此问题无关 - 我使用 H2 作为数据库,并且在与持久层交互时只使用 Spring 的 @Repository 接口,所以没有写一行 SQL
更新
不幸的是,我认为支持以下注释:
@OnDelete(action = OnDeleteAction.CASCADE)
并且 JUnit 测试批准了所需行为的正确工作,因此回答了我的问题。
@Test
public void test() {
// stores an Business object in db and returns the saved object
Business b = createBusiness();
// stores an Process object in db and returns the saved object
Process p = createProcess();
// stores Assignmnent object with both relations in db and returns the saved object
Assignment a = createAssignment(b, p);
assertThat(a).isNotNull();
// deletes Process object from db
processService.delete(p);
assertThat(processService.getById(p.getId())).isNull();
assertThat(assignmentService.getById(a.getId())).isNull();
assertThat(businessService.getById(b.getId())).isNotNull();
}
但事实并非如此。在我的 JavaFX 应用程序中,删除被记录下来,看起来它正在工作,但是当之后查询数据库时,实体仍然在 table 中,尽管在 JUnit 测试中它不是...... 如果有人能对这个问题有所启发,我将不胜感激。
如果需要任何进一步的信息,我当然会提供。非常感谢您帮助我。
编辑 最后我解决了这个问题并通过以下设置获得了我想要的行为:
商业
@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(mappedBy = "business", orphanRemoval = true)
@OnDelete(action = OnDeleteAction.CASCADE)
private List<Assignment> assignments;
作业
@ManyToOne
@JoinColumn(name = "business_id")
private Business business;
@ManyToOne
@JoinColumn(name = "process_id")
private Process process;
进程
@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(mappedBy = "process", orphanRemoval = true)
@OnDelete(action = OnDeleteAction.CASCADE)
private List<Assignment> assignments;
请注意添加的注释@OnDelete(action = OnDeleteAction.CASCADE)
。这个提示来自 here。我在这里省略了 Hibernate 文档,因为它们(恕我直言)没有提供比链接的 SO post.
更新:
还要考虑删除的 cascade
属性,这不是必需的,因为我正在使用休眠 @OnDelete
.