I found a very strange behaviour using Hibernate as JPA implementation. I don't know, but it looks like a bug.
Code:
@Entity
public class User {
@Id
@GeneratedValue
private Long id;
@Column(unique = true)
private String name;
@Column
private String password;
@ManyToMany(cascade = { CascadeType.ALL })
@JoinTable(name = "u_f", joinColumns = { @JoinColumn(name = "u") }, inverseJoinColumns = { @JoinColumn(name = "f") })
private Set<User> friends = new HashSet<User>();
public User() {}
public void addFriend(User friend) {
friends.add(friend);
}
from UserDao:
Code:
@Override
public void startSession() {
em = emf.createEntityManager();
}
@Override
public void closeSession() {
em.close();
}
@Override
public User makePersistent(User entity) {
try {
em.getTransaction().begin();
entity = em.merge(entity);
em.getTransaction().commit();
return entity;
} finally {
if (em.getTransaction().isActive())
em.getTransaction().rollback();
}
}
Test code:
Code:
UserDao userDao = new UserDao();
userDao.startSession();
User first = new User("gigi", "a");
first = userDao.makePersistent(first);
userDao.closeSession();
userDao.startSession();
User second = new User("kux", "a");
User third = new User("qwe", "asd");
first.setPassword("ffs");
first.addFriend(second);
first = userDao.makePersistent(first);
first.addFriend(third);
first = userDao.makePersistent(first);
userDao.closeSession();
Now, what happens when running the test is that all 3 beans get added to the User table, but only User second is added as a friend of User first. This means that the second merge done on the same EntityManager on a different transaction doesn't merge the friends Set.
Here is a snapshot of the database after runnig the code:
User:
1 gigi
2 kux
3 qwe
u_f:
1 2
Looking forward for your opinion.