Как добавить movie_id и user_id в таблицу «movie_added_by»

#java #spring-boot #hibernate #spring-data-jpa

#java #весенняя загрузка #впасть в спящий режим #spring-data-jpa

Вопрос:

У меня уже есть модель пользователя. Теперь я создал модель фильма, мое требование состоит в том, что всякий раз, когда какой-либо существующий пользователь собирается добавить какой-либо фильм, в это время user_id и movie_id будут храниться в таблице movie_added_by.

Здесь пользовательская модель должна сопоставить один ко многим с movie_added_by, и аналогично фильм будет сопоставлен с movie_added_by.

Для лучшего понимания вы можете обратиться к схеме базы данных.

введите описание изображения здесь

Я действительно не знаю, как я могу это сделать, используя аннотацию гибернации

Модель пользователя выглядит следующим образом:

 @Getter
@Setter
public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id", unique = true, nullable = false)
    private Integer user_id;
    
    private String name;    
} 
 

Модель фильма выглядит следующим образом:

 @Getter
@Setter
public class Movie implements Serializable
{
    private static final long serialVersionUID = -6790693372846798580L;
 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "movie_id", unique = true, nullable = false)
    private Integer movie_id;
 
    private String movie_name;
} 
 

Ответ №1:

Вероятно, вы хотите создать связь @ManyToMany между объектами. Есть 2 способа сделать это (с помощью промежуточной таблицы, созданной явно или с помощью гибернации.

При простом подходе ваши объекты будут выглядеть следующим образом:

 public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id", unique = true, nullable = false)
    private Integer user_id;
    
    private String name;

    @ManyToMany(cascade = CascadeType.Persist)
    @JoinTable(name="user_movie", 
    joinColumns = {@JoinColumn(name="user_id")},
    inverseJoinColumns = {@JoinColumn(name="movie_id)})
    private Set<Movie> movies = new HashSet<>();
    
} 

public class Movie implements Serializable
{
    private static final long serialVersionUID = -6790693372846798580L;
 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "movie_id", unique = true, nullable = false)
    private Integer movie_id;
 
    private String movie_name;

    @ManyToMany(cascade = CascadeType.Persist, mappedBy = "movies" //field from the user class responsible for mapping)
    private Set<User> users = new HashSet<>()



} 


 

Итак, в основном здесь вы указываете Hibernate создать промежуточную таблицу и сохранить там соответствующие идентификаторы этих 2 объектов. Пара других заметок здесь:

a) возможно, вам захочется изменить тип переменной id с Integer на Long на случай, если ваши объекты растут;

б) Если вы аннотировали столбец с помощью @Id, вам не нужно использовать unique= true и nullable = false в аннотации столбца;

c) помните о реализации конструктора без аргументов;

d) не забудьте исключить файлы отношений из методов equals(), hashCode() и toString();

Существует другой способ, при котором вы явно создаете модель для связей, сохраняемых в таблице. Это может пригодиться, когда выяснится, что вам нужно хранить больше данных в «таблице отношений». В этом случае ваши объекты будут выглядеть следующим образом:

 public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id", unique = true, nullable = false)
    private Integer user_id;
    
    private String name;

    @OnetToMany(cascade = CascadeType.PERSIST, mappedBy = "user")
    private Set<AddedMovie> addedMovies = new HashSet<>()
    
}

public class Movie implements Serializable
{
    private static final long serialVersionUID = -6790693372846798580L;
 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "movie_id", unique = true, nullable = false)
    private Integer movie_id;
 
    private String movie_name;

    @OneToMany(cascade = CascadeType.PERSIST, mappedBy = "movie")
    private Set<AddedMovie> moviesAddedByUser = new HashSet<>();

} 

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Entity
public class AddedMovie{
    @Id
    @GeneratedValue
    private Long id;
    @ManyToOne(cascade = CascadeType.PERSIST)
    @JoinColumn(name = "user_id")
    private User user;
    @ManyToOne(cascade = CascadeType.PERSIST)
    @JoinColumn(name = "movie_id")
    private Movie movie;

// sine this entity has now its own lifecycle, you can add more fields here
    private Integer rating;
    private LocalDateTime movieAddedOn;
}



 

Комментарии:

1. Спасибо за подробную информацию. Я проверю и сообщу yiu

2. да, это работает, просто внесите некоторые незначительные изменения