#java #spring #hibernate #jpa #spring-security
#java #spring #переход в спящий режим #jpa #spring-безопасность
Вопрос:
У меня есть объект User
:
@Entity
@Table(name = "users")
public class User {
(...)
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "users_roles",
joinColumns = @JoinColumn(name = "user_id", nullable = false),
inverseJoinColumns = @JoinColumn(name = "role_id", nullable = false)
)
private List<Role> roles;
}
и объект Role
с простыми id
и name
столбцами.
User
и Role
имеет отношение многие ко многим с таблицей объединения users_roles
.
Я создал метод для удаления пользователя:
public void remove(long userId) {
Session session = getSession();
//NativeQuery joinTableQuery = session.createNativeQuery("DELETE FROM users_roles ur WHERE ur.user_id = :userId");
//joinTableQuery.setParameter("userId", userId);
//joinTableQuery.executeUpdate();
Query userQuery = session.createQuery("DELETE FROM User u WHERE u.id = :userId");
userQuery.setParameter("userId", userId);
userQuery.executeUpdate();
}
Я специально закомментировал первый NativeQuery, чтобы проверить, что произойдет. И что интересно, теперь Hibernate генерирует два запроса:
- Hibernate: удалить из users_roles, где (user_id) в (выберите идентификатор из users, где id =?)
- Hibernate: удалять из пользователей, где id =?
Вопрос:
Почему Hibernate генерирует дополнительный запрос к users_roles
(join table), в то время как мой User
объект не имеет отношения CascadeType.REMOVE
set on @ManyToMany
? Я думал, что должен написать это сам (прокомментированная часть).
Ответ №1:
Вашей User
сущности принадлежит связь «многие ко многим» с Role
сущностью. Когда вы удаляете User
, Hibernate автоматически также удаляет все записи из таблицы ассоциаций. Но это не каскадирует операцию удаления для Role
объекта.
Вы никогда не должны использовать CascadeType.REMOVE
для ассоциации «многие ко многим». Если вы удалите объект, Hibernate удалит все связанные объекты, даже если на них все еще ссылаются другие объекты. Я очень подробно объяснил это в своем блоге.
Если бы вы использовали CascadeType.REMOVE
в своей roles
ассоциации и удалили User
, Hibernate удалил бы все Role
объекты, на которые ссылается это User
. Это будет сделано, даже если есть другие User
объекты entity, которые связаны с этими Role
объектами.