简体   繁体   中英

Spring + JPA many to many relationship

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 (ie 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!

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.

you're only removing the users from the group, that's not enough. you need to remove all the users from the group and remove that group from all those users' list of groups .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM