我有一个类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的另一个副本。