我已经映射了一对多,如下
//TourPackage model
@OneToMany(mappedBy = "packages", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<Itinerary> itineraries;
public Set<Itinerary> getItineraries() {
return itineraries;
}
行程模型
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="packages_id", nullable = false)
@OnDelete(action = OnDeleteAction.CASCADE)
private TourPackage packages;
现在我的更新功能,更新表单返回tourPackage和多个行程,所以我想做的是删除所有以前的行程并插入新的行程。据我所知,我已经写了//null returned
的地方应该返回该包裹的所有行程,但返回空。
@PostMapping("/update-tour-package")
public String updateTourPackage(@ModelAttribute("tourPackage") TourPackage tourPackage, @RequestParam String[] day, @RequestParam String[] itinerary_title, @RequestParam String[] itinerary_description, @RequestParam String[] itinerary_altitude) {
TourPackage tour = this.tourPackageService.saveTourPackage(tourPackage);
this.itineraryRepo.deleteAll(tour.getItineraries());//null returned for itinerary
for (int i = 0; i < day.length; i++) {
Itinerary ite = new Itinerary();
ite.setPackages(tour);
ite.setDay(day[i]);
ite.setTitle(itinerary_title[i]);
ite.setDescription(itinerary_description[i]);
ite.setAltitude(itinerary_altitude[i]);
this.itineraryRepo.save(ite);
}
return "redirect:/";
}
我做得对吗?请给我指正确的方向。如果我应该为这个问题提供更多的背景,请发表评论。
因为除非您在其他地方有配置来将现有的TourPackage设置为模型对象,否则@ModelAttribute("tourPackage") TourPackage tourPackage
将是一个新实例。
如果你想修改一个现有的实例,那么通过一个带有ID的隐藏字段发送,并在你的控制器中添加一个方法:
@ModelAttribute
public TourPackage getTourPackage(@RequestParam(name = "tourPckageId", required = false) Long id){
//load from repo if id is not null or otherwise new instance
}
现在updateTourPackage方法将接收上面返回的现有实例。
https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann方法
您应该这样更改代码:
@Transactional
public void deleteAll(TourPackage tourPackage) { // Some param here
TourPackage tour = this.tourPackageService.saveTourPackage(tourPackage);
this.itineraryRepo.deleteAll(tour.getItineraries());//null returned for itinerary
for (int i = 0; i < day.length; i++) {
// Do the same with your code.
}
}
@PostMapping("/update-tour-package")
public String updateTourPackage(@ModelAttribute("tourPackage") TourPackage tourPackage) {
tourPacakageService.deleteAll(tourPackage);
}
原因如下:
- 使用fetchType设置@OneToMany为Lazy=>只要您处于会话或持久性上下文中,当您需要时,行程就会变得更晚
- 在springJPA中,持久性上下文的默认范围是事务。调用saveTourPackage(tourPackage(后,事务已经结束。这就是为什么你会得到无效的行程