Spring boot JPA сохраняет множество однонаправленных отношений

#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. Это работает, спасибо !