2015-06-02 53 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'仍然需要在那裏。謝謝。 –