Reputation: 365
I have a class A
that can have an association to multiple B
s (one-to-many):
@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;
}
}
and class B
storing a reference to 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;
}
}
When I now execute the following code Hibernate will save two entries in tables b
both having the name b1
. I do not know how to avoid this or what I am doing wrong.
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();
Upvotes: 0
Views: 116
Reputation: 1426
I think you should be saving a1 and a2 instead of merging them. From the javadocs, this is what merge does.
Copy the state of the given object onto the persistent object with the same identifier. If there is no persistent instance currently associated with the session, it will be loaded. Return the persistent instance. If the given instance is unsaved, save a copy of and return it as a newly persistent instance. The given instance does not become associated with the session. This operation cascades to associated instances if the association is mapped with cascade="merge".
So, since you are cascading merge you are merging b. But b is unsaved, so a copy of b will be saved. So merging a1 will save a copy of b, and merging a2 will save another copy of b.
Upvotes: 1
Reputation: 18123
You can achieve this by inventing a mapping table between A and B (which then has two entries by itself), because every B stores the reference to its A in a column and as the first normal form of databases state, you only have atomic values and so no single B line with two primary keys of A in one column.
Upvotes: 0