Hibernate尝试两次持久保存同一个对象

时间:2015-08-06 09:01:09

标签: java hibernate jpa

我有3个类对应3个表VDPD的FK为VFK_V),并使用OneToMany关系加入。此外,他们退出第4个表格V_D_P,其中包含VDP的关系。

以下是这些数据模型的样子:

@Entity
@Table(name = "V")                                                   
public class V {

     @Id
     @GeneratedValue(strategy = GenerationType.SEQUENCE)
     @Column(name = "ID")
     private Long id;

    @OneToMany(cascade=CascadeType.ALL)
    @JoinColumn(name = "FK_V", referencedColumnName="Id", nullable = false)
    private Set<D> d;

    @OneToMany(cascade=CascadeType.ALL)
    @JoinColumn(name = "FK_V", referencedColumnName="Id", nullable = false)
    private Set<V_D_P> vdp;

    //Getters Setters etc.
}


@Entity
@Table(name = "V_D_P")
public class V_D_P {

      @Id
      @GeneratedValue(strategy = GenerationType.SEQUENCE)
      @Column(name = "ID")
      private Long id;

     @ManyToOne(cascade=CascadeType.ALL)
     @JoinColumn(name = "FK_D", nullable = false)
     private D d;

     @ManyToOne(cascade=CascadeType.ALL)
     @JoinColumn(name = "FK_P", nullable = false)
     private P p;

     //Getters Setters etc.       
}

@Entity
@Table(name = "D")                                                   
public class D {
      @Id
      @GeneratedValue(strategy = GenerationType.SEQUENCE)
      @Column(name = "ID")
      private Long id;

    //Getters Setters etc.
}

@Entity
@Table(name = "P")                                                  
public class P {

      @Id
      @GeneratedValue(strategy = GenerationType.SEQUENCE)
      @Column(name = "ID")
      private Long id;

    //Getters Setters etc.
}

现在我希望将VDP与他们的关系持续存在。我是

V v = new V();

D d = new D();
Set<D> dSet = new HashSet<>();
dSet.add(d);
v.setD(dSet); // Adding d to V ....(1)

P p = new P();
V_D_P vdp = new V_D_P();

vdp.setD(d); // Adding d to V_D_P ....(2)
vdp.setP(p);

Set<V_D_P> vdpSet = new HashSet<V_D_P>();
vdpSet.add(vdp);
v.setVdp(vdpSet);

entityManager.persist(v);

现在你可以看到我正在两次添加相同的d对象。一次到P,一次到V_D_P。但是,由于它们是相同的对象,因此只能存在一次。但是根据hibernate日志,我看到hibernate试图插入2个不同的对象。

我还看到以下例外: ORA-00001:唯一约束

有没有办法让hibernate这些是相同的对象并且只持久一次?

3 个答案:

答案 0 :(得分:6)

对象由id唯一标识。因此他们必须具有相同的ID。

  • 要么提供之前的ID,
  • 或者保留一次并在保存另一个之前刷新d对象(因此它设置了id)。

答案 1 :(得分:2)

尝试使用save()代替persist()。如this post中所述,持久化并不一定会立即更新对象的ID。这意味着hibernate可能会遇到你的'd&#39;对象两次遍历对象图。两次它都可以说&#34; id为null,我需要插入一个新的!&#34;。

显然这种行为没有明确定义,所以在所有情况下都不会发生。

答案 2 :(得分:1)

你真的需要VDP.d字段:你不能只使用V和V之间的双向(映射)关系(D)P(V(D)P会有av字段)而且只是导航V(D)Pvd?