Весна: как отправить запрос в отношение ManyToMany - PullRequest
1 голос
/ 18 марта 2020

У меня есть две сущности, Meal и Mealplan в отношении @ManyToMany. Каждый План Питания состоит из пяти объектов Питания.

Питание:

@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;

* Например, 1026 * из /mealplan/1 выглядит следующим образом:

{
id: 1,
calendarweek: 10,
mealsPerWeek: [
   {
   id: 4,
   name: "Linsensuppe",
   price: 23.5,
   art: "vegan"
   },
   {
   id: 3,
   name: "Salat",
   price: 3,
   art: "vegetarisch"
   },

Теперь я хочу создать (настраиваемый?) Метод для добавления еды в план питания. Каков наилучший способ сделать это? Я думал о собственном методе в моем репозитории, например:

@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);
}

Не работает, например, плюс я не могу объявить метод в интерфейсе. Нужен ли для этого новый класс?

1 Ответ

1 голос
/ 18 марта 2020

Я бы go с чем-то вроде этого:

Обязательно создайте интерфейс 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;
    }
}

А в контроллере автосервис и выполнить. Хорошие вещи об этом вы можете дополнительно обезопасить и изящно поймать, если кто-то пытается изменить не существующий план питания или нет его (с некоторыми дополнительными логами c в обслуживании)

@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();
            }
    } 

POST-запрос на /mealplan/1/add с тело нового приема пищи (где 1 - ваш mealPlanId, к которому следует добавить блюдо).

Контроллер вызовет сервисную службу, которая попытается сначала найти план питания на основе переданного идентификатора _mealPlanRepository.findById(mealPlanId)

Это вернет Необязательный, и мы объединяем операцию получения значения, вызывая _mealPlanRepository.findById(mealPlanId).orElseThrow(MealNotFoundException::new)

. На найденном объекте мы добавляем наш новый прием пищи (он будет сохранен из-за транзакций, но вы можете вызвать _mealPlanRepository.save() для него вместо

Если все сделано в основном, сервис ретус обновляется, а контроллер затем возвращает объект ответа с обновленным планом питания

...