I'm very new to Spring and I'm trying to make a many-to-many relationship work as I expect. The relationships works fine, the tables are created and the data is inserted correctly. What I expect, is that when I empty a List (i.e. I empty the ArrayList "users" from an object of type "Group"), I expect the system to remove the relationships from the database - but it doesn't.
I have the following classes:
@Entity
@Table(name = "`group`")
public class Group
{
@Id
@GeneratedValue
@Column(name = "id")
private int id;
@Column(name = "name")
private String name;
@ManyToMany(cascade = {CascadeType.ALL})
@JoinTable(
name = "`user_has_group`",
joinColumns = @JoinColumn(name = "group_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id")
)
private List<User> users = new ArrayList<User>();
...
}
@Entity
@Table(name = "`user`")
public class User
{
@Id
@GeneratedValue
@Column(name = "id")
private int id;
@Column(name = "name")
private String name;
@ManyToMany(mappedBy = "users")
private List<Group> groups = new ArrayList<Group>();
...
}
Here are the DAOs:
@Repository
public class GroupJpaDao implements GroupDao
{
private EntityManager em;
@Transactional
public void save(Group group)
{
this.em.merge(group);
}
...
@PersistenceContext
void setEntityManager(EntityManager entityManager)
{
this.em = entityManager;
}
}
@Repository
public class UserJpaDao implements UserDao
{
private EntityManager em;
@Transactional
public void save(User user)
{
this.em.merge(user);
}
...
@PersistenceContext
void setEntityManager(EntityManager entityManager)
{
this.em = entityManager;
}
}
Here is the test method:
@Test
public void test()
{
Group g = new Group();
g.setName("Test group");
groupDao.save(g); // Works fine - inserts the group into the database
User u = new User();
u.setName("Test user");
userDao.save(u); // Works fine - inserts the user into the database
g.addUser(u);
groupDao.save(g); // Works fine - adds the many-to-many relationship into the database
g.removeAllUsers();
groupDao.save(g); // Doesn't work - I'm expecting it to remove all the related relationships from the database but it doesn't!
}
Am I doing something wrong or is it something not possible to do?
Any hint is really appreciated.
Thank you!
In JPA we use the @ManyToMany annotation to model many-to-many relationships. This type of relationship can be unidirectional or bidirectional: In a unidirectional relationship only one entity in the relationship points the other. In a bidirectional relationship both entities point to each other.
In JPA, we use the @ManyToMany annotation to model Many to Many Relationships. It could either be Uni-directional or Bi-directional. In a unidirectional association, only one entity points to another. In a bidirectional association, both the entities point to each other.
Hibernate. Hibernate Mapping. Learn to create and manage many-to-many relationships between entities in a hibernate/JPA-based applications using @ManyToMany annotation. A many-to-many association is made between two entities where one entity can be associated with multiple other instances of the other entity.
I reread your question, and now the answer is clear. Your create a Group g
, and save it. But since your save method uses merge
, and you don't take into account the value returned by merge
to assign it to g
, you keep merging the transient group g, which never has any ID assigned. So, each time merge is called, you actually create a new group rather than modifying the previously created one.
Change the save method to
public Group save(Group group)
{
return this.em.merge(group);
}
and always reassign the result to g
:
g = groupDao.save(g);
Of course, the same must be done for the user.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With