Java 注释映射与XML映射及删除实体

Java 注释映射与XML映射及删除实体,java,hibernate,jpa,wildfly-8,Java,Hibernate,Jpa,Wildfly 8,我正在将项目从XML映射迁移到纯粹的基于JPA注释的映射,在尝试删除(删除)和实体及其子对象时遇到了问题。它适用于XML映射,而不适用于注释映射 XML映射如下所示: <set name="evaluations" order-by="evalDate desc" table="Evaluation" lazy="true" inverse="true" cascade="delete"> <key column="requestId" /> <on

我正在将项目从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(cascade=CascadeType.REMOVE)
@JoinColumn(name = "requestId", insertable=false, updatable=false)
@OrderBy("evalDate DESC")
private Set<Evaluation> evaluations = new TreeSet<>();
其中,上述
评估
服务请求
的子对象。Hibernate4.3.7是我正在使用的JPA Impl,运行在WildFly 8.2上

当Hibernate设置为吐出其SQL时,执行带有注释的删除操作时,Hibernate会生成一个查询以查找实体引用,然后当调用
remove
时,它会生成一个更新,试图将
Evaluation
FK中的子记录更新回ServiceRequest为空:

Hibernate: update Evaluation set requestId=null where requestId=?
这是因为
requestId
上有一个
notnull
约束

如果我使用XML映射执行相同的操作(请参见上面的代码片段),它就可以正常工作。所有子实体将与父实体一起删除。而Hibernate只会在从不尝试更新任何内容的情况下产生
选择
删除


这感觉就像我的注释映射出错了,但我无法确定哪里出错了。请帮助。

我认为您需要指定级联注释。当心。

谢谢@troy的指导。单独添加级联不起作用,但是添加
insertable=flase,updateable=false
起作用。因此注释映射现在如下所示:

<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(cascade=CascadeType.REMOVE)
@JoinColumn(name = "requestId", insertable=false, updatable=false)
@OrderBy("evalDate DESC")
private Set<Evaluation> evaluations = new TreeSet<>();
@OneToMany(cascade=CascadeType.REMOVE)
@JoinColumn(name=“requestId”,insertable=false,updateable=false)
@订购人(“评估说明”)
私有集求值=新树集();
我不知道这到底是为什么,所以如果有人能解释一下,我将不胜感激


我是间接来到这里的。首先,我向这个映射添加了一个
null-false
,当我部署它时,Hibernate对此表示不满,并告诉我需要将
insert=false-update=false
添加到
Evaluation
实体上的
requestId
。这种方法奏效了。我可以随意删除,但无法保存或插入评估。我有点期待这会发生。所以我只是厌倦了这个解决方案,它起了作用

您的xml配置实际上表示ServiceRequest和Set之间的关系是双向的,因为inverse=“true”

但是您的JPA注释是单向的。所以这应该是可行的(根据OP的评论编辑)

@OneToMany(orphaneremovation=true,mappedBy=“requestId”)
@订购人(“评估说明”)
私有集求值=新树集();

这里
mappedBy=“requestId”
告诉Hibernate这是关系的所有者端。所以它将发出语句来删除求值。

我认为当您设置inverse=“true”时,您的xml配置实际上是双向关系。使用JPA注释,现在您已经设置了“insertable=false,Updateable=false”,这创建了一个虚拟的inverse=“true”。这就是它起作用的原因。哦,我想如果你把@OneToMany(orphanRemoving=true)放回去,它也会起作用。JPA有自己的inverse=true注释,请看这里@OneToMany(mappedBy=“ServiceRequest”)是的,放回
orphanlRemoval=true
也可以,但不是单独放回
insertable=false,updateable=false
仍然需要存在。谢谢。在这个过程中,我还了解到,
orphanRemoving=true
包含一个隐式的
CascadeType.REMOVE
,因此当指定
orphanRemoving=true
时,您不需要指定
cascade=CascadeType/REMOVE
谢谢,这是一个正确的方向,只需稍加修改。将此映射更改放入Hibernate后,Hibernate抱怨同时使用了
mappedBy
@JoinColumn
,但有一个例外:
标记为mappedBy的关联不能定义像@JoinTable或@JoinColumn:hci.hrccadmin.model.ServiceRequest.evaluation这样的数据库映射。然后在删除
@JoinColumn
之后,它不喜欢
mappedBy=“ServiceRequest”
,所以我将它改为
mappedBy=“requestId”
,因为这是将ServiceRequest链接到评估的FK,而且似乎有效。看起来有点奇怪,但我想这是有道理的。谢谢@sarahthebutterfly的回答。它真的又开始动了。
@OneToMany(orphanRemoval=true,mappedBy="requestId")
@OrderBy("evalDate DESC")
private Set<Evaluation> evaluations = new TreeSet<>();