2015-06-02 104 views
1

我正在将项目从XML映射迁移到基于纯JPA批注的映射,并且在尝试删除(删除)以及实体及其子项时遇到问题。它适用于XML映射,不适用于注释映射。注解映射与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); 

当上述EvaluationServiceRequest子对象。 Hibernate 4.3.7是我正在使用的JPA Impl,在WildFly 8.2上运行。

使用Hibernate设置为BARF了其SQL,执行与到位的Hibernate的注释映射删除生成的查询来查找实体引用,然后在remove被称为它产生的更新试图更新子在Evaluation FK回ServiceRequest记录为空:

Hibernate: update Evaluation set requestId=null where requestId=? 

这打击了,因为有上requestId一个not null约束。

如果我使用XML映射执行相同的操作(请参阅上面的代码片段),它工作得很好。所有子实体都与父级一起删除。而休眠只产生selectsdeletes,如果从未尝试更新什么。

这感觉就像我有注解映射错误,但我无法确定我出错的地方。请帮忙。

回答

1

你xml配置其实说你的ServiceRequest和Set之间的关系是双向的,因为inverse =“true”。

但您的JPA注释是单向的。所以这应该工作(OP的评论后编辑)

@OneToMany(orphanRemoval=true,mappedBy="requestId") 
@OrderBy("evalDate DESC") 
private Set<Evaluation> evaluations = new TreeSet<>(); 

这里mappedBy="requestId"告诉Hibernate,这是关系的业主方。所以它会发布声明来删除评估。

+0

谢谢,这是正确的方向,稍作修改。在Hibernate中进行映射更改后,抱怨使用'mappedBy'和'@ JoinColumn'两个例外:'标记为mappedBy的关联不能像@JoinTable或@JoinColumn那样定义数据库映射:hci.hrccadmin.model.ServiceRequest.evaluations' 。然后删除'@ JoinColumn'后,它不喜欢'mappedBy =“ServiceRequest”',所以我将它改为'mappedBy =“requestId”',因为这是将ServiceRequest连接到评估的FK,并且似乎工作。似乎有点奇怪,但我想这是有道理的。 –

+0

谢谢@sarahthebutterfly的答案。它真的再次移动。 –

0

谢谢@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。这种工作。我可以像我想的那样删除,但我无法保存或插入评估。我有点期待会发生。所以我只是厌倦了这个解决方案,它工作。

+1

我认为你的xml配置实际上是双向关系,因为你设置了inverse =“true”。使用JPA注释,现在您已经设置了“insertable = false,updatable = false”,它创建了一个虚拟inverse =“true”。这就是它工作的原因。哦,我想如果你把@OneToMany(orphanRemoval = true)放回去,它也会起作用。 – sarahTheButterFly

+0

而JPA拥有自己的inverse = true批注,请参阅http://stackoverflow.com/questions/4865285/inverse-true-in-jpa-annotations。 @OneToMany(mappedBy =“ServiceRequest”) – sarahTheButterFly

+0

是的,放回'orphanlRemoval = true'也可以,但并不孤单。 'insertable = false,updatable = false'仍然需要在那里。谢谢。 –