注释映射与 XML 映射和删除实体
Annotation mapping vs. XML mapping and deleting an entity
我正在将项目从 XML 映射迁移到基于纯 JPA 注释的映射,我 运行 在尝试删除(删除)实体及其子实体时遇到了问题。它适用于 XML 映射,不适用于注释映射。
XML 映射如下所示:
<set name="evaluations" order-by="evalDate desc" table="Evaluation" lazy="true" inverse="true" cascade="delete">
<key column="requestId" />
<one-to-many class="org.stuff.model.Evaluation" />
</set>
注释映射,据我所知是这样的:
@OneToMany(orphanRemoval=true)
@JoinColumn(name = "requestId")
@OrderBy("evalDate DESC")
private Set<Evaluation> evaluations = new TreeSet<>();
这是一个单向关系。
删除实体的 JPA 代码是:
ServiceRequest sr = em.getReference(ServiceRequest.class, id);
em.remove(sr);
其中上面的Evaluation
是ServiceRequest
的子对象。 Hibernate 4.3.7 是我正在使用的 JPA Impl,运行 在 WildFly 8.2 上。
将 Hibernate 设置为 barf out 其 SQL,使用 annotation 映射执行删除 Hibernate 会生成查询以查找实体引用,然后在何时remove
被调用它产生一个更新,试图将 Evaluation
FK 中的子记录更新回 ServiceRequest 为空:
Hibernate: update Evaluation set requestId=null where requestId=?
因为 requestId
.
上有 not null
约束,所以爆炸了
如果我使用 XML 映射(参见上面的代码片段)执行相同的操作,它就可以正常工作。所有子实体都与父实体一起删除。如果从不尝试 更新 任何东西,Hibernate 只会生成 selects
和 deletes
。
感觉好像注解映射错了,但又想不通哪里错了。请帮忙。
我认为您需要指定级联注释。当心this issue though.
感谢@troy 的指导。单独添加级联不起作用,但添加 insertable=flase, updateable=false
可以。所以注释映射现在看起来像这样:
@OneToMany(cascade=CascadeType.REMOVE)
@JoinColumn(name = "requestId", insertable=false, updatable=false)
@OrderBy("evalDate DESC")
private Set<Evaluation> evaluations = new TreeSet<>();
我不确定为什么会这样,所以如果有人能解释一下,我将不胜感激。
我是间接来到这里的。首先,我向此映射添加了一个 nullable-false
,当我部署它时,Hibernate 抱怨它并告诉我我需要在 Evaluation
实体上将 insert=false update=false
添加到 requestId
。那种工作。我可以随意删除,但无法保存或插入评价。我有点期待那会发生。所以我只是厌倦了这个解决方案并且它起作用了。
你 xml 配置实际上说你的 ServiceRequest 和 Set 之间的关系是双向的,因为 inverse = "true"。
但是您的 JPA 注释是单向的。所以这应该有效(在 OP 的评论后编辑)
@OneToMany(orphanRemoval=true,mappedBy="requestId")
@OrderBy("evalDate DESC")
private Set<Evaluation> evaluations = new TreeSet<>();
这里 mappedBy="requestId"
告诉 Hibernate 这是关系的所有者端。因此它将发布声明以删除评估。
我正在将项目从 XML 映射迁移到基于纯 JPA 注释的映射,我 运行 在尝试删除(删除)实体及其子实体时遇到了问题。它适用于 XML 映射,不适用于注释映射。
XML 映射如下所示:
<set name="evaluations" order-by="evalDate desc" table="Evaluation" lazy="true" inverse="true" cascade="delete">
<key column="requestId" />
<one-to-many class="org.stuff.model.Evaluation" />
</set>
注释映射,据我所知是这样的:
@OneToMany(orphanRemoval=true)
@JoinColumn(name = "requestId")
@OrderBy("evalDate DESC")
private Set<Evaluation> evaluations = new TreeSet<>();
这是一个单向关系。
删除实体的 JPA 代码是:
ServiceRequest sr = em.getReference(ServiceRequest.class, id);
em.remove(sr);
其中上面的Evaluation
是ServiceRequest
的子对象。 Hibernate 4.3.7 是我正在使用的 JPA Impl,运行 在 WildFly 8.2 上。
将 Hibernate 设置为 barf out 其 SQL,使用 annotation 映射执行删除 Hibernate 会生成查询以查找实体引用,然后在何时remove
被调用它产生一个更新,试图将 Evaluation
FK 中的子记录更新回 ServiceRequest 为空:
Hibernate: update Evaluation set requestId=null where requestId=?
因为 requestId
.
not null
约束,所以爆炸了
如果我使用 XML 映射(参见上面的代码片段)执行相同的操作,它就可以正常工作。所有子实体都与父实体一起删除。如果从不尝试 更新 任何东西,Hibernate 只会生成 selects
和 deletes
。
感觉好像注解映射错了,但又想不通哪里错了。请帮忙。
我认为您需要指定级联注释。当心this issue though.
感谢@troy 的指导。单独添加级联不起作用,但添加 insertable=flase, updateable=false
可以。所以注释映射现在看起来像这样:
@OneToMany(cascade=CascadeType.REMOVE)
@JoinColumn(name = "requestId", insertable=false, updatable=false)
@OrderBy("evalDate DESC")
private Set<Evaluation> evaluations = new TreeSet<>();
我不确定为什么会这样,所以如果有人能解释一下,我将不胜感激。
我是间接来到这里的。首先,我向此映射添加了一个 nullable-false
,当我部署它时,Hibernate 抱怨它并告诉我我需要在 Evaluation
实体上将 insert=false update=false
添加到 requestId
。那种工作。我可以随意删除,但无法保存或插入评价。我有点期待那会发生。所以我只是厌倦了这个解决方案并且它起作用了。
你 xml 配置实际上说你的 ServiceRequest 和 Set 之间的关系是双向的,因为 inverse = "true"。
但是您的 JPA 注释是单向的。所以这应该有效(在 OP 的评论后编辑)
@OneToMany(orphanRemoval=true,mappedBy="requestId")
@OrderBy("evalDate DESC")
private Set<Evaluation> evaluations = new TreeSet<>();
这里 mappedBy="requestId"
告诉 Hibernate 这是关系的所有者端。因此它将发布声明以删除评估。