我在@ManyToMany关系中有两个实体Meal
和Mealplan
。每个Mealplan包含五个Meal对象。
用餐:
@Entity
public class Meal {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private BigDecimal price;
private String type;
@ManyToMany(mappedBy = "mealsPerWeek")
private List<Mealplan> mealplan;
}
用餐计划:
public class Mealplan {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private int calendarweek;
@ManyToMany
private List<Meal> mealsPerWeek;
例如/mealplan/1
的JSON如下所示:
{
id: 1,
calendarweek: 10,
mealsPerWeek: [
{
id: 4,
name: "Linsensuppe",
price: 23.5,
art: "vegan"
},
{
id: 3,
name: "Salat",
price: 3,
art: "vegetarisch"
},
现在,我想创建(自定义?)方法以将餐添加到Mealplan中。最好的方法是什么?我在考虑这样的自定义方法:
@RestController
@RequestMapping("/mealplan")
@CrossOrigin(origins = "*", allowedHeaders = "*")
public class MealplanController {
@PostMapping
public void addMealToMealplan(@RequestBody Meal meal) {
mealplanRepository.addMealToMealplan(essen);
}
但是如何将这个自定义方法添加到存储库中?这种方法的效果如何?
@Repository
public interface MealplanRepository extends JpaRepository<Mealplan, Integer> {
void addMealToMealplan(Meal meal);
}
例如不起作用,而且我无法在接口中声明方法。我需要一个新的班级吗?
答案 0 :(得分:1)
我会选择这样的东西:
确保创建MealRepository jpa接口
@Repository
public interface MealRepository extends JpaRepository<Meal, Integer> {
}
然后最好创建MealPlanService来处理对对象的任何操作(不要在控制器中进行实际工作),同时注入两个存储库。每当我们添加新餐时,我们都将其持久保存,然后将其添加到餐计划对象的餐中。事务性以自动更新膳食计划(您可以手动调用保存膳食计划)
@Service
public class MealPlanService{
private MealRepository _mealRepository;
private MealPlanRepository _mealPlanRepository;
@Autowire
MealPlanService(MealRepository mealRepository,MealPlanRepository mealPlanRepository)
_mealRepository = mealRepository
_mealPlanRepository = mealPlanRepository
}
@Transactional
public Mealplan addMealToMealplan(int mealPlanId, Meal meal) throws MealNotFoundException{
Mealplan mealplan = _mealPlanRepository.findById(mealPlanId).orElseThrow(MealNotFoundException::new)
meal = _mealRepository.save(meal);
mealplan.getMealsPerWeek().add(meal)
return mealplan;
}
}
然后在Controller autowire服务中执行。不错的东西,如果有人尝试更改不存在的就餐计划或不更改其就餐计划,您还可以安全并优雅地捕获(使用某些额外逻辑)
@RestController
@RequestMapping("/mealplan")
@CrossOrigin(origins = "*", allowedHeaders = "*")
public class MealplanController {
private MealPlanService _mealPlanService;
@Autowire
MealplanController (MealPlanService mealPlanService){
_mealPlanService = mealPlanService;
}
@PostMapping(path = "/{mealPlanId}/add")
public ResponseEntity<MealPlan> addMealToMealplan(@PathVariable int mealPlanId , @RequestBody Meal meal) {
try{
return ResponseEntity.ok(_mealPlanService.addMealToMealplan(meal));
catch (MealNotFoundException e){
//do some other logic, return error , log it or smth
ResponseEntity.notFound().build();
}
}
在/mealplan/1/add
上发布带有新餐的邮件(其中1是您的mealPlanId
,应添加餐)。
控制器将呼叫服务服务,该服务将尝试首先根据传递的ID _mealPlanRepository.findById(mealPlanId)
这将返回Optional,我们通过调用_mealPlanRepository.findById(mealPlanId).orElseThrow(MealNotFoundException::new)
然后在找到的实体上添加新餐(由于Transactional,它将继续存在,但是您可以在其上调用_mealPlanRepository.save()
而不是
如果一切都已完成,则服务将更新实体,然后控制器将返回带有更新膳食计划的Response实体