2015-02-10 151 views
0

我有我的應用程序的麻煩folloing:休眠@OneToMany合併錯誤

我有一個關係@OneToMany如上圖:

酒吧類:

@Entity 
public class Bar { 

    @Id 
    private Long id; 

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST) 
    @JoinTable(name = "bar_foo_relation", 
     joinColumns = { @JoinColumn(name = "id", referencedColumnName = "bar_id") }, 
     inverseJoinColumns = { @JoinColumn(name = "id", referencedColumnName = "foo_id") }) 
    private List<Foo> fooList; 

    // Getters & Setters 

} 

Foo類:

@Entity 
public class Foo { 

    @Id 
    private Long id; 

    private String fooValue; 

    // Getters & Setters 

} 

當我創建欄的新實例,與fooList稀少,像這樣:

{ 
    "id": null, 
    "fooList": [ 
    { 
     "id": null, 
     "fooValue": "foo" 
    }, 
    { 
     "id": null, 
     "fooValue": "foo" 
    } 
    ] 
} 

我打電話給manager.persist(bar),它工作得很好。

DB表吧:

 
row | id 
----+---- 
01 | 01 

DB bar_foo_relation表:

 
row |bar_id|foo_id 
----+------+------ 
01 | 01| 01 
01 | 01| 02 

DB富表:

 
row | id|foovalue 
----+----+-------- 
01 | 01|foo 
02 | 02|foo 

但是,當我把新的Foo實例是這樣的:

{ 
    "id": 1, 
    "fooList": [ 
    { 
     "id": 1, 
     "fooValue": "foo" 
    }, 
    { 
     "id": 2, 
     "fooValue": "foo" 
    }, 
    // New instance of Foo to persist 
    { 
     "id": null, 
     "fooValue": "foo" // fooValue is setted 
    }, 
    // New instance of Foo to persist 
    { 
     "id": null, 
     "fooValue": "foo" // fooValue is setted 
    } 
    ] 
} 

,並呼籲manager.merge(bar)美孚的新情況下,這發生在DB: DB表吧:

 
row | id 
----+---- 
01 | 01 

DB bar_foo_relation表:

 
row |bar_id|foo_id 
----+------+------ 
01 | 01| 01 
01 | 01| 02 
01 | 01| 03 // New instance of Foo got persisted and is referenced here 
01 | 01| 04 // New instance of Foo got persisted and is referenced here 

DB富表:

 
row | id|foovalue 
----+----+-------- 
01 | 01|foo 
02 | 02|foo 
02 | 03|null  // New instance of Foo without foovalue 
02 | 04|null  // New instance of Foo without foovalue 

新Foos的列fooValeu設置爲null

我不知道它爲什麼會發生。有人能澄清我嗎?

我的環境是: 的Java 1.7 的PostgreSQL 9.3 休眠4.3.6.Final

+1

如果您在其中添加CascadeType.MERGE會發生什麼? (cascade = {CascadeType.REFRESH,CascadeType.MERGE})事實上,你試圖通過調用Bar上的merge來保存Foo的新實例似乎不正確。 – zmf 2015-02-10 17:11:38

+0

謝謝。我添加了** CascadeType.MERGE **,這是工作。回答問題。我會投票並標記解決。 – brbrbr 2015-02-10 17:41:37

回答

2

嘗試使用以下:

級聯= {CascadeType.PERSIST,CascadeType.MERGE}

我相信你所看到的行爲(雖然我不是100%肯定的)是當你在非持久化的子對象上調用合併時,實體管理器知道有關聯的對象,但是因爲它們不是持久化上下文的一部分,所以默認構造函數的Foo被稱爲後面場面。告訴你的父對象級聯合並操作或手動保存子對象會阻止這種情況發生。

+0

Foo實體本身不會被持久化。僅Bar實體... mappedBy選項需要引用Foo類上的屬性,但是沒有任何屬性可以在實體上引用。 – brbrbr 2015-02-10 16:52:11

+0

上面的評論引用了我以前的答案,此後被編輯爲更正確的答案。 – zmf 2015-02-10 18:41:43