我有两个名为SeriesDBModel和SermonDBModel的类;系列包含许多布道。
在SermonDBModel中,我有
@ManyToOne
@JoinColumn(name="series_id", nullable = false)
private SeriesDBModel series;
在SeriesDBModel中,我有
@JoinColumn(name="series_id")
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true )
private List<SermonDBModel> sermons = new ArrayList<>();
我通过此调用持久保存数据(服务只包含标准的spring-data-jpa存储库),
final SeriesDBModel persisted = this.seriesDBService.save(seriesDBModel);
似乎写入数据库正常(db在sermons表中的seriesId中具有正确的值),并且使用SermonDBModel返回SeriesDBModel。但是,返回的SermonDBModel中的系列字段为null。
当前正在发生的是控制器通过服务保留数据,然后在将保存的模型对象转换回DTO以发送回调用者时,它失败(在Sermon类中),因为在布道模型对象上的关系未正确设置(即系列为空)。
控制器方法:
@RequestMapping(method = RequestMethod.POST,
value = "/series",
produces = APPLICATION_JSON_VALUE)
public ResponseEntity<FBCApiResponse<Series>> create(@RequestBody SeriesDBModel seriesDBModel){
FBCApiResponse<Series> response;
if(seriesDBModel.getId() != null && seriesDBService.findById(seriesDBModel.getId()).isPresent()){
logger.error("Can't create an entity that already exists");
response = new FBCApiResponse<Series>(null,"Can't create an entity that already exists" );
}
else{
logger.info(String.format("Saving or updating series %s", seriesDBModel));
final SeriesDBModel persisted = this.seriesDBService.save(seriesDBModel);
final Series series = new Series(persisted);
response = new FBCApiResponse<Series>(series, HttpStatus.OK);
}
return new ResponseEntity<FBCApiResponse<Series>>(response, response.getStatusCode());
}
系列DTO:
public Series(final SeriesDBModel seriesDBModel){
this.id = seriesDBModel.getId();
this.title = seriesDBModel.getTitle();
this.imageURI = Optional.of(URI.create(seriesDBModel.getImageURL()));
final List<SermonDBModel> sermonDBModels = seriesDBModel.getSermons();
this.sermons = (CollectionUtils.isEmpty(sermonDBModels)) ?
Optional.empty() :
Optional.of(
sermonDBModels.stream()
.map(s -> Sermon.fromDBModel(s))
.collect(Collectors.toList())
);
final Stats stats = new Stats(seriesDBModel.getPlays(), seriesDBModel.getLikes(), seriesDBModel.getShares());
this.stats = Optional.of(stats);
this.tags = Optional.ofNullable(seriesDBModel.getTags()).map(tagList -> new HashSet<>(tagList));
}
Sermon DTO (由于系列为空,目前正在以NullpointerException爆炸)
public static Sermon fromDBModel(final SermonDBModel sermonDBModel){
final int id = sermonDBModel.getId();
final String title = sermonDBModel.getTitle();
final String speaker = sermonDBModel.getSpeaker();
final String series = sermonDBModel.getSeries().getTitle();
final LocalDate date = sermonDBModel.getDate();
final String seriesLink = "/series/" + sermonDBModel.getSeries().getId();
final Optional<URI> mp3URI = Optional.ofNullable(sermonDBModel.getMp3Url()).map(URI::create);
final Optional<URI> imageURI = Optional.ofNullable(sermonDBModel.getImageUrl()).map(URI::create);
final Optional<URI> pdfURI = Optional.ofNullable(sermonDBModel.getImageUrl()).map(URI::create);
final Stats stats = new Stats(sermonDBModel.getPlays(), sermonDBModel.getLikes(), sermonDBModel.getShares());
final Optional<List<String>> tags = Optional.ofNullable(sermonDBModel.getTags());
final Optional<Set<String>> tagSet = tags.map(list -> new HashSet(list));
return new Sermon(id, title, speaker, series, Optional.of(seriesLink), date, mp3URI, imageURI, pdfURI, Optional.of(stats), tagSet);
}
注意,我可以通过在保留返回的Series后立即添加一行来“修复”此问题。但是,这似乎是一个黑客。为什么hibernate不会为我建立这种关系?
persisted.getSermons().forEach(sermon -> sermon.setSeries(persisted));