0

In my system, User is the owner side of a many-to-many relationship.

User.class

@Entity
public class User {

    @Id
    private UUID id;

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "user_rooms",
            joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "room_id"))
    private Set<Room> rooms = new HashSet<>();
}

Room.class

@Entity
public class Room {

    @Id
    private UUID id;

    @ManyToMany(mappedBy = "rooms", fetch = FetchType.LAZY)
    public Set<User> users = new HashSet<>();
}

With the JSON below, I can create a User and automatically associate him with an existing Room.

Creating a User

{
    "nickname":"bob",
    "rooms":[{
        "id":"ca6eabb6-747e-47ec-9b52-c09483f7572a"
    }]
}

But when I do the same thing on the non-owner side (Room), it doesn't work. The creation is successful, but the association does not happen.

Creating a Room

{
    "name":"cool_room",
    "users":[{
        "id":"a5744044-1e6a-4279-8731-28f1e7dfc148"
    }]
}

Is it possible to associate user_rooms from the non-owner side?

1 Answers1

0

Yes, it's possible, but for correct saving both side of the bidirectional association should be in-sync. So, you should correct your entities in this way:

@Entity
public class User {

    @Id
    private UUID id;

    @ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinTable(name = "user_rooms",
            joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "room_id"))
    private Set<Room> rooms = new HashSet<>();

    public void addRoom(Room room) {
        rooms.add( room );
        room.getUsers().add( this );
    }

    // public void removeRoom(Room room)
    // can be implemented in the similar way if it's needed
}

@Entity
public class Room {

    @Id
    private UUID id;

    @ManyToMany(mappedBy = "rooms", fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    public Set<User> users = new HashSet<>();

    public void addUser(User user) {
        users.add( user );
        user.getRooms().add( this );
    }

    // public void removeUser(User user)
    // can be implemented in the similar way if it's needed
}

See also this part of documentation.

SternK
  • 11,649
  • 22
  • 32
  • 46