fix(server): fix duplicate Ingredient present in each recipe
An issue where multiple instances of a uniquely named Ingredient are stored in the database. This is patched by checking server-side whether an ingredient exists before persisting it. This now correctly implements the Many-to-Many reference.
This commit is contained in:
parent
2d1df8fc11
commit
d497ed108e
2 changed files with 21 additions and 15 deletions
|
|
@ -22,6 +22,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import server.database.IngredientRepository;
|
||||
import server.database.RecipeIngredientRepository;
|
||||
import server.database.RecipeRepository;
|
||||
|
||||
|
|
@ -34,16 +35,16 @@ public class RecipeController {
|
|||
private final RecipeRepository recipeRepository; // JPA repository used in this controller
|
||||
private final SimpMessagingTemplate messagingTemplate;
|
||||
private final RecipeIngredientRepository recipeIngredientRepository;
|
||||
private final IngredientController ingredientController;
|
||||
private final IngredientRepository ingredientRepository;
|
||||
|
||||
public RecipeController(RecipeRepository recipeRepository,
|
||||
SimpMessagingTemplate messagingTemplate,
|
||||
IngredientController ingredientController,
|
||||
IngredientRepository ingredientRepository,
|
||||
RecipeIngredientRepository recipeIngredientRepository) {
|
||||
this.recipeRepository = recipeRepository;
|
||||
this.messagingTemplate = messagingTemplate;
|
||||
this.recipeIngredientRepository = recipeIngredientRepository;
|
||||
this.ingredientController = ingredientController;
|
||||
this.ingredientRepository = ingredientRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -80,7 +81,19 @@ public class RecipeController {
|
|||
|
||||
return ResponseEntity.ok(recipeRepository.findAll());
|
||||
}
|
||||
|
||||
private Recipe saveRecipeAndDependencies(Recipe recipe) {
|
||||
recipe.getIngredients()
|
||||
.forEach(recipeIngredient ->
|
||||
recipeIngredient.setIngredient(
|
||||
ingredientRepository
|
||||
.findByName(recipeIngredient.getIngredient().name)
|
||||
.orElseGet(() -> ingredientRepository.save(recipeIngredient.getIngredient())
|
||||
))
|
||||
);
|
||||
recipeIngredientRepository.saveAll(recipe.getIngredients());
|
||||
Recipe saved = recipeRepository.save(recipe);
|
||||
return saved;
|
||||
}
|
||||
/**
|
||||
* Mapping for <code>POST /recipe/{id}</code>.
|
||||
* Also creates the ingredient elements if they do not exist.
|
||||
|
|
@ -94,11 +107,7 @@ public class RecipeController {
|
|||
if (!recipeRepository.existsById(id)) {
|
||||
return ResponseEntity.badRequest().build();
|
||||
}
|
||||
recipe.getIngredients().stream()
|
||||
.map(recipeIngredient -> recipeIngredient.ingredient)
|
||||
.forEach(ingredientController::createIngredient);
|
||||
recipeIngredientRepository.saveAll(recipe.getIngredients());
|
||||
Recipe saved = recipeRepository.save(recipe);
|
||||
Recipe saved = saveRecipeAndDependencies(recipe);
|
||||
messagingTemplate.convertAndSend(Topics.RECIPES, new UpdateRecipeMessage(saved));
|
||||
|
||||
return ResponseEntity.ok(saved);
|
||||
|
|
@ -128,12 +137,7 @@ public class RecipeController {
|
|||
if (recipeRepository.exists(Example.of(example))) {
|
||||
return ResponseEntity.badRequest().build();
|
||||
}
|
||||
// FIXME reduce code duplication
|
||||
recipe.getIngredients().stream()
|
||||
.map(recipeIngredient -> recipeIngredient.ingredient)
|
||||
.forEach(ingredientController::createIngredient);
|
||||
recipeIngredientRepository.saveAll(recipe.getIngredients());
|
||||
Recipe saved = recipeRepository.save(recipe);
|
||||
Recipe saved = saveRecipeAndDependencies(recipe);
|
||||
messagingTemplate.convertAndSend(Topics.RECIPES, new CreateRecipeMessage(saved));
|
||||
|
||||
return ResponseEntity.ok(saved);
|
||||
|
|
|
|||
|
|
@ -6,9 +6,11 @@ import org.springframework.data.domain.Pageable;
|
|||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface IngredientRepository extends JpaRepository<Ingredient, Long> {
|
||||
List<Ingredient> findAllByOrderByNameAsc();
|
||||
Page<Ingredient> findAllByOrderByNameAsc(Pageable pageable);
|
||||
Optional<Ingredient> findByName(String name);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue