我有一个类A,可以与多个B(一对多)关联:

@Entity
@Table(name = "a")
public class A implements Serializable {

 private static final long serialVersionUID = 6796905221158242611L;

 @Id
 @GeneratedValue
 @Column(name = "a_id")
 private Long a_id;

 @Column(name = "name")
 private String name;

 @OneToMany(mappedBy = "a", cascade = CascadeType.ALL)
 private Set<B> bs;

 public void addB(B b) {
  if(bs == null)
   bs = new HashSet<B>();

  bs.add(b);
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }
}


和类B存储对A的引用:

@Entity
@Table(name = "b")
public class B implements Serializable {

 private static final long serialVersionUID = 6063558165223241323L;

 @Id
 @GeneratedValue
 @Column(name = "b_id")
 private Long b_id;

 @Column(name = "name")
 private String name;

 @ManyToOne(cascade = CascadeType.ALL)
 @JoinColumn(name = "a_id")
 private A a;

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public A getA() {
  return a;
 }

 public void setA(A a) {
  this.a = a;
 }
}


当我现在执行以下代码时,Hibernate将在表b中保存两个条目,两个条目的名称均为b1。我不知道如何避免这种情况或我做错了什么。

EntityManagerFactory emf = Persistence.createEntityManagerFactory(Configurations.MYSQL);
EntityManager em = emf.createEntityManager();

em.getTransaction().begin();

A a1 = new A();
a1.setName("a1");

A a2 = new A();
a2.setName("a2");

B b = new B();
b.setName("b1");

a1.addB(b);
a2.addB(b);

em.merge(a1);
em.merge(a2);

em.getTransaction().commit();

最佳答案

我认为您应该保存a1和a2而不是合并它们。从javadocs,这就是合并的作用。


使用以下命令将给定对象的状态复制到持久对象上:
相同的标识符。如果当前没有持久实例
与会话相关联,它将被加载。返回持久
实例。如果给定的实例未保存,请保存副本并返回
作为新持久实例。给定的实例不成为
与会话相关联。该操作级联到
关联映射为cascade =“ merge”的实例。


因此,由于您是级联合并,因此您正在合并b。但是b未保存,因此将保存b的副本。因此,合并a1将保存b的副本,而合并a2将保存b的另一个副本。

07-24 09:38
查看更多