#spring-boot #spring-data-jpa #many-to-many
Вопрос:
У меня есть проект Spring Boot (с JHipster) с 2 объектами JPA : Пользователем и фильмом.
Я создал однонаправленные многомерные отношения между ними. Пользователь является владельцем отношений.
Я хотел бы добавить фильмы в список избранных фильмов пользователя (свойство «избранное» в сущности пользователя).
Но когда я пытаюсь добавить фильм в список избранного, в таблице «user_film_favorite» (объединенная таблица между 2 объектами) ничего не сохраняется.
Сопоставление кажется нормальным, потому что, когда я вручную ввожу данные в эту таблицу объединения, я могу получить список фильмов для пользователя.
Я искал здесь много подобных проблем, но не могу найти, в чем проблема.
Пользователь сущности :
@Entity @Table(name = "jhi_user") @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) public class User extends AbstractAuditingEntity implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; // Other properties @ManyToMany(cascade = CascadeType.PERSIST) @JoinTable( name = "user_film_favorite", joinColumns = { @JoinColumn(name = "user_id", referencedColumnName = "id") }, inverseJoinColumns = { @JoinColumn(name = "movie_id", referencedColumnName = "id") } ) @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) @BatchSize(size = 20) private Listlt;Filmgt; favorites = new ArrayListlt;gt;();
Сущность Фильма :
@Entity @Table(name = "film") @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public class Film implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private Long id; @NotNull @Column(name = "title", nullable = false) private String title; @Column(name = "plot") private String plot; @Column(name = "rating") private Float rating;
ФильМсервис :
/** * Add one film to current user favorites. * * @param id the id of the film. * @return the film saved into user favorites. */ @Transactional(readOnly = true) public Optionallt;FilmDTOgt; addToFavorites(Long id) { log.debug("Request to get Film : {}", id); Optionallt;Filmgt; filmOpt = filmRepository.findById(id); // Get current logged user with his favorites Optionallt;Usergt; userOpt = userService.getUserWithFavorites(); if (filmOpt.isPresent() amp;amp; userOpt.isPresent()) { User user = userOpt.get(); user.getFavorites().add(filmOpt.get()); userService.save(user); } return filmOpt.map(filmMapper::toDto); }
Обслуживание пользователей :
/** * Save a user. * * @param user the entity to save. * @return the persisted entity. */ public User save(User user) { log.debug("Request to save User : {}", user); return userRepository.save(user); }
Если бы кто-нибудь мог мне помочь, это было бы действительно круто ! Заранее спасибо 🙂
Ответ №1:
Вы читаете пользователя из базы данных, поэтому вызов сохранения вызовет вызов EntityManger.merge
. Для этого вам также необходимо добавить
CascadeType.MERGE
к ManyToMany
составлению карты.
Комментарии:
1. Спасибо за ваш ответ. Я добавил каскадный тип. СЛИЯНИЕ с моим отображением, но проблема все еще возникает, у меня нет записи в таблице соединений.
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) @JoinTable( name = "user_film_favorite", joinColumns = { @JoinColumn(name = "user_id", referencedColumnName = "id") }, inverseJoinColumns = { @JoinColumn(name = "movie_id", referencedColumnName = "id") } ) private Listlt;Filmgt; favorites = new ArrayListlt;gt;();
2. Почему транзакция помечена как только для чтения? Удалите это
3. Это работает, спасибо !