2015-02-10 114 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