我有三个具有双向多对一映射的实体:
@MappedSuperclass
@Getter
@Setter
abstract class Media {
@Id
@Column
@GeneratedValue(strategy = GenerationType.SEQUENCE)
protected Long id;
@Column(name = "imdb_id")
private String imdbId;
@Column(name = "api_movie_id")
private String apiMovieId;
@Column
private Long metadataItemIdentity;
@Column
protected String title;
@Column(name = "original_title")
protected String originalTitle;
@Column
protected String studio;
@Column
protected Double rating;
@Column(length = 500)
protected String description;
@Column(name = "content_rating")
protected String contentRating;
@Column
protected String genres;
@Column
protected String director;
@Column
protected Long duration;
@Column
protected String writer;
@Column
protected String stars;
@Column(name = "year_of_release")
protected Integer year;
@Column(name = "country_code")
protected String countryCode;
@Column(name = "is_ok")
protected boolean isOk = true;
@Column(name = "audio_lang")
protected String audioLanguage = "";
@Column(name = "sub_lang")
protected String subtitlesLanguage = "";
@Column(name = "api_name")
protected String apiName;
}
@Entity(name = "seasons")
@Getter
@Setter()
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Season {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column
protected Long id;
@Column
private Long metadataItemIdentity;
@ManyToOne
@JoinColumn(name = "fk_series")
private Series series;
@OneToMany(mappedBy = "season", cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private List<Episode> episodes;
private Integer number;
}
@Entity(name = "series")
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Series extends Media {
@OneToMany(mappedBy = "series", cascade = {CascadeType.PERSIST, CascadeType.MERGE})
List<Season> seasons;
}
现在保存的逻辑是:
@Service
@Slf4j
public class SeriesMigrateServiceImpl implements SeriesMigrateService {
private final SeriesService seriesService;
private final MetaDataItemRepository metaDataItemRepository;
private final ModelMapper modelMapper;
@Autowired
public SeriesMigrateServiceImpl(SeriesService seriesService,
MetaDataItemRepository metaDataItemRepository,
ModelMapper modelMapper) {
this.seriesService = seriesService;
this.metaDataItemRepository = metaDataItemRepository;
this.modelMapper = modelMapper;
}
@Override
public void migrateSeries() {
List<Series> allSeries = this.getAllSeriesFromSqlite();
allSeries.forEach(this::populateSeasons);
seriesService.saveSeries(allSeries);
}
private void populateSeasons(Series series) {
List<Season> allSeasons = this.getAllSeasonsForSeriesFromSqlite(series);
allSeasons.forEach(season -> season.setSeries(series));
allSeasons.forEach(this::populateEpisodes);
series.setSeasons(allSeasons);
}
private void populateEpisodes(Season season) {
List<Episode> allEpisodes = this.getAllEpisodesForSeasonFromSqlite(season);
allEpisodes.forEach(episode -> episode.setSeason(season));
season.setEpisodes(allEpisodes);
}
private List<Series> getAllSeriesFromSqlite() {
return metaDataItemRepository
.findAllSeries().stream()
.map(item -> this.convert(item, Series.class))
.collect(Collectors.toList());
}
private List<Season> getAllSeasonsForSeriesFromSqlite(Series series) {
return metaDataItemRepository
.findAllByParentIdentityAndMetadataType(series.getMetadataItemIdentity(), 3).stream()
.map(item -> this.convert(item, Season.class))
.collect(Collectors.toList());
}
private List<Episode> getAllEpisodesForSeasonFromSqlite(Season season) {
return metaDataItemRepository
.findAllByParentIdentityAndMetadataType(season.getMetadataItemIdentity(), 4).stream()
.map(item -> this.convert(item, Episode.class))
.collect(Collectors.toList());
}
private <T> T convert(MetaDataItem item, Class<T> classType) {
return modelMapper.map(item, classType);
}
}
会发生什么情况,有时Hibernate会保存两次实体,例如,如果我有840个媒体文件,Hibernate会保存1680个?而令我最困扰的是,有时正确工作有时却没有?有什么建议么? *编辑
@Service
public class SeriesServiceImpl implements SeriesService {
private final SeriesRepository seriesRepository;
@Autowired
public SeriesServiceImpl(SeriesRepository seriesRepository) {
this.seriesRepository = seriesRepository;
}
@Override
@Transactional
public List<Series> saveSeries(List<Series> series) {
return seriesRepository.save(series);
}
}