1

我有一个 JPA 实体“请求”,它拥有一个答案列表(也是 JPA 实体)。这是它在 Request.java 中的定义方式:

@OneToMany(cascade= CascadeType.ALL, mappedBy="request")
private List<Answer> answerList;

在 Answer.java 中:

@JoinColumn(name = "request", referencedColumnName="id")
@ManyToOne(optional = false)
private Request request;

在程序执行过程中,请求的答案列表可能会添加或删除答案,或者可能会替换实际的列表对象。因此,我的问题是:当我将 Request 合并到数据库时,曾经在 List 中的 Answer 对象保留在数据库中——也就是说,Request 不再持有引用的 Answer 对象(间接地,通过列表)不会被删除。

这不是我想要的行为,好像我将一个请求合并到数据库,然后再次获取它,它的答案列表可能不一样。我犯了一些编程错误吗?是否有注释或设置可以确保数据库中的答案与请求列表中的答案完全相同?

一种解决方案是保留对原始答案列表的引用,然后在合并请求之前使用 EntityManager 删除每个旧答案,但似乎应该有一种更清洁的方法。

4

4 回答 4

1

在 JPA 1.0 中,您想做的事情无法由 JPA 完成。简而言之,所有关系管理都必须由应用程序完成,包括从集合中删除任何孤儿(这是您想要做的)。

在 JPA 2.0 中,它们确实支持(虽然我不知道细节),但是根据您的实现,升级可能并不容易或不可能。

您也可以直接使用 Hibernate 之类的东西,但仍然使用许多 JPA 1.0 注释等。我也无法提供详细信息。

就我而言,我编写了通用代码来通过反射自动处理集合的合并。

于 2009-12-15T15:52:02.880 回答
1

使用 EclipseLink 并将 @PrivateOwned 注释添加到 answerList 会有所帮助。

于 2010-05-06T10:03:00.257 回答
0

在映射关系中指定附加属性是非法的。您可以在 Request 中使用 @DependentElement 注释。

于 2009-12-15T15:36:43.367 回答
0

如果你使用 Hibernate 作为 JPA 提供者,你可以添加一个

@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)

在答案列表上。除了您已经在那里使用的 JPA 注释之外,这将起作用。JPA 2(目前大多数/所有 JPA 提供者都没有生产就绪的实现)可以自行执行此操作。

于 2010-05-06T11:53:00.480 回答