Основная проблема, которую я вижу, заключается в том, что вы неправильно установили атрибуты mappedBy=
. Значением должно быть имя поля в сущности owning
, например, rooms
вместо room
.
@ManyToMany(mappedBy = "rooms")
private Set<User> userList;
Кроме того, не используйте FetchType.EAGER
без конкретного варианта использования, и я не знаю, что это за вариант использования. Это приведет только к головным болям. Вы должны создавать конкретные запросы для извлечения отношений, когда они необходимы.
Если ваша таблица Room
имеет внешний ключ creator_id
, тогда у вас есть отношение OneToMany
, а не ManyToMany
. ManyToMany
отношения должны использовать соединительную таблицу, чтобы быть реализованными. ФК может реализовать только отношения OneToMany
. Здесь вы также должны правильно установить аннотацию mappedBy
.
@OneToMany(mappedBy="creator")
private Set<Room> rooms;
и
@ManyToOne
private User creator;
В аннотации mappedBy
указывается сущность-владелец.
Поле, которому принадлежат отношения. Требуется, если отношения не являются однонаправленными.
Вы использовали bidirectional
отображений, поэтому вы используете mappedBy
аннотации. Смысл владения сущностью - это сущность, которая отвечает за сохранение отношения. В вашем примере Room
отвечает за сохранение отношения creator
, а User
отвечает за сохранение отношения user_role
. Окончательный результат может быть
@Entity
public class User {
@ManyToMany
@JoinTable(name = "user_role",
joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")},
inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")}
)
private Set<Role> roles;
@OneToMany(mappedBy="creator")
private Set<Room> rooms;
@Entity
public class Role {
@ManyToMany(mappedBy = "roles")
private Set<User> users;
@Entity
public class Room {
@ManyToOne
private User creator;
и простой пример использования этого через spring-data-jpa
может быть
Role r1 = new Role();
roleRepo.save(r1);
User u1 = new User();
// needed to persist relation
u1.setRoles(Collections.singleton(r1));
// added to improve accuracy
r1.setUsers(Collections.singleton(u1));
userRepo.save(u1);
Room m1 = new Room();
// needed to persist relation
m1.setCreator(u1);
// added to improve accuracy
u1.setRooms(Collections.singleton(m1));
roomRepo.save(m1);
Обратите внимание, что вы должны специально управлять обеими сторонами двунаправленных отношений при использовании определенного экземпляра без его обновления:
Java Persistence API требует, чтобы ссылки были установлены на обеих сторонах отношения. Это означает, что вам необходимо явно вызвать b.setA (a) и a.setB (b).
И так u1.setRooms (Collections.singleton (m1)); и r1.setUsers (Collections.singleton (u1)); добавляется, чтобы у текущего экземпляра пользователя и роли были точные комнаты и коллекции пользователей. Если эти экземпляры будут перезагружены из базы данных позже с новым вызовом JPA, что типично, то в этом нет необходимости.