英文:
how to get all child data and then delete in spring boot
问题
以下是翻译好的部分:
我已经按照以下方式映射了一对多关系
//TourPackage 模型
@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;
现在我的更新函数,更新表单返回旅行包和多个行程,所以我想要做的是删除所有先前的行程并插入新的行程。在我写的地方 "//null returned" 据我所知应该返回该套餐的所有行程,但返回 null。
@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:/";
}
我做得对吗?请指导我正确的方向。如果需要提供更多上下文,请进行评论。
英文:
I have mapped one to many as follows
//TourPackage model
@OneToMany(mappedBy = "packages", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<Itinerary> itineraries;
public Set<Itinerary> getItineraries() {
return itineraries;
}
in itinerary model
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="packages_id", nullable = false)
@OnDelete(action = OnDeleteAction.CASCADE)
private TourPackage packages;
now my update function, update form returns tourPackage and multiple itinerary, so what I want to do is delete all previous itinerary and insert new ones. Where I have written //null returned
to my knowledge should return all the itinerary of that package but returns null.
@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:/";
}
am I doing it right? please point me in right direction. Please comment if I should provide more context to the question.
答案1
得分: 1
因为除非您在其他地方有配置来设置现有的TourPackage作为模型对象,否则@ModelAttribute("tourPackage") TourPackage tourPackage
将是一个新实例。
如果您想要修改现有实例,则通过带有ID的隐藏字段发送,并在您的控制器中添加一个方法:
@ModelAttribute
public TourPackage getTourPackage(@RequestParam(name = "tourPckageId", required = false) Long id){
//如果id不为空,则从repo加载,否则创建新实例
}
现在,updateTourPackage方法将接收上述方法返回的现有实例。
链接:https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-methods
英文:
Because unless you have config elsewhere to set an existing TourPackage as the model object, @ModelAttribute("tourPackage") TourPackage tourPackage
will be a new instance.
If you want to modify an existing instance then send through a hidden field with the ID and add a method inn your controller:
@ModelAttribute
public TourPackage getTourPackage(@RequestParam(name = "tourPckageId", required = false) Long id){
//load from repo if id is not null or otherwise new instance
}
Now the updateTourPackage method will receive the existing instance returned by the above.
https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-methods
答案2
得分: 1
你应该像这样更改代码:
@Transactional
public void deleteAll(TourPackage tourPackage) { // 这里有一些参数
TourPackage tour = this.tourPackageService.saveTourPackage(tourPackage);
this.itineraryRepo.deleteAll(tour.getItineraries());//对于行程,返回null
for (int i = 0; i < day.length; i++) {
// 用你的代码做相同的操作。
}
}
@PostMapping("/update-tour-package")
public String updateTourPackage(@ModelAttribute("tourPackage") TourPackage tourPackage) {
tourPacakageService.deleteAll(tourPackage);
}
这是为什么:
- 你使用了@OneToMany,并且fetchType为Lazy => 当你需要时,itineraries会在稍后获取,只要你在会话或持久性上下文中。
- 在Spring JPA中,持久性上下文的默认范围是事务。在调用saveTourPackage(tourPackage)之后,事务已经结束。这就是为什么你会得到行程为null的原因。
英文:
You should change code like this:
@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);
}
Here is why:
- You set @OneToMany with fetchType is Lazy => itineraries will get latter when you need it as long as you are in a session or persistence context.
- In spring JPA, the default scope of persistence context is transaction. After you call saveTourPackage(tourPackage) the transaction has end. That why you will get null for it itineraries.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论