java - 无法在 Intellij IDEA 的 Spring Boot 中添加一个等于和哈希码的实体?
问题描述
我有一个关于在电影实体中添加更多类型的问题。因为我在更新类型方面有更新电影的问题,如新值所示。这就是为什么我在所有以流派、导演和电影命名的实体中使用equals
和。hashcode
我曾经把它建在Intellij IDEA
但是,当我调用getMovieById
and时,我只显示第一种流派,同时又添加了一个流派updateMovieById
。
我该如何解决这个问题?
这是我的项目链接:项目链接
这是我的流派、电影和导演的 equals 和 hashcode 方法。我只添加流派的一个。
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Genre)) return false;
Genre genre = (Genre) o;
return Objects.equals(getId(), genre.getId());
}
@Override
public int hashCode() {
return Objects.hash(getId());
}
这是我的测试类,如下所示。
@Test
void createMovie() throws ParseException {
Movie movie = new Movie();
movie.setName("Movie A");
movie.setRating(7.5);
Director movieDirector = new Director();
movieDirector.setName("Director 1");
movie.setDirector(movieDirector);
Genre genreFirst = new Genre();
genreFirst.setName("Adventure");
genreFirst.setMovie(movie);
Genre genreSecond = new Genre();
genreSecond.setName("Action");
genreSecond.setMovie(movie);
movie.addGenre(genreFirst);
movie.addGenre(genreSecond);
Movie createdMovie = movieService.save(movie);
System.out.println("createdMovie Id : " + createdMovie.getId());
assertThat(createdMovie.getId()).isGreaterThan(0);
}
编辑
这是我的 updateMovieById,如下所示。
@Test
void updateMovieById() throws ParseException {
createMovie();
Long id = 1L;
Movie movie = movieService.findById(id).get();
movie.setName("Movie B");
movie.setRating(7.5);
Director movieDirector = new Director();
movieDirector.setName("Director 2");
movie.setDirector(movieDirector);
LocalDate now = Utils.formatDate(LocalDate.of(2019, Month.JANUARY, 1));
movie.setCreatedAt(now);
Genre genreFirst = new Genre();
genreFirst.setName("Historical");
genreFirst.setMovie(movie);
Genre genreSecond = new Genre();
genreSecond.setName("Horror");
genreSecond.setMovie(movie);
movie.addGenre(genreFirst);
movie.addGenre(genreSecond);
Movie updatedMovie = movieService.update(id,movie);
assertThat(updatedMovie.getId()).isGreaterThan(0);
}
当我更新电影时,类型如下所示。我该如何解决这个问题?
MovieService | update | Movie Genre : Adventure
MovieService | update | Movie Genre : Action
MovieService | update | Movie Genre : Historical
MovieService | update | Movie Genre : Horror
解决方案
问题是您将Genre
a 存储在Set
类Movie
中。
@OneToMany(mappedBy="movie",cascade = CascadeType.PERSIST,fetch = FetchType.EAGER)
private Set<Genre> genres = new HashSet<>();
只要Genre
实例没有保存在数据库中,它们id
仍然是null
,所以 equals/hashcode 实现会将它们视为相等,并且其中只有 1 个保留在Set
(aSet
不允许重复)中。
如果要保留 id 由数据库分配的事实,则需要像这样实现 equals 和 hashcode:
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Genre gene = (Genre) o;
return id != null &&
id.equals(genre.id);
}
@Override
public int hashCode() {
return getClass().hashCode();
}
有关更多信息,请参阅如何使用 JPA 实体标识符实现 equals 和 hashCode,或参阅Equals 和 hashcode implementation 注意事项以获得更广泛的讨论。
另一种实现是使用早期主键生成,您首先生成主键并手动将其传递给构造函数。
推荐阅读
- php - 如何声明一个变量以用于 Laravel 6 及以上 laravel 版本中的所有函数?
- c++ - 有条件地声明成员函数的简单 SFINAE 问题
- stanford-nlp - 我可以在不下载语言模块的情况下运行 stanza NER 吗?
- php - php + mysql still commiting
- django - 如何向 Django 添加禁用属性
- css - react bootstrap中如何保持图片和卡片的大小比例一致?
- xml - 为什么 xs:precisionDecimal 不是 XSD1.1 的一部分?
- javascript - Vue.js:在方法中使用计算属性返回未定义的错误
- google-cloud-platform - 有没有办法确定 GCP 上的自定义机器类型是 N1 还是 N2?
- python - Python:使用列表作为字典键