我正在使用Product
,Recipe
,Menu
进行应用。
表Product
包含id
,name
,category
列。
@Entity
@Table(name = "products")
public class Product {
@Id
@GeneratedValue
private long id;
@Column(name = "name")
private String name;
@Column(name = "category")
@Enumerated(EnumType.STRING)
private Category category;
}
表Recipe
的ID为name
。
@Table(name = "recipes")
@Entity
public class Recipe {
@Id
@GeneratedValue
private long id;
@Column(name = "name")
private String name;
@ManyToMany(cascade = CascadeType.DETACH ,fetch = FetchType.EAGER)
@JoinTable(name = "product2recipe",
joinColumns = {@JoinColumn(name = "recipe_id")},
inverseJoinColumns = {@JoinColumn(name = "product_id")})
private List<Product> products;
}
表Menu
有id
,name
。
@Entity
@Table(name = "menus")
public class Menu {
@Id
@GeneratedValue
private long id;
@Column(name = "name")
private String name;
@ManyToMany(cascade = CascadeType.REMOVE,fetch = FetchType.EAGER)
@JoinTable(name = "recipe2menu",
joinColumns = {@JoinColumn(name = "menu_id")},
inverseJoinColumns = {@JoinColumn(name = "recipe_id")})
private List<Recipe> recipes;
}
我将产品配方与表格product2recipe
以及配方菜单与recipe2menu
表格相关联。
Recipe
可以包含许多Products
,而Product
可以包含在许多Recipe
中,因此它与ManyToMany关系。
Menu
包含许多Recipes
,Recipes
可以包含多个Menu
,因此它也是ManyToMany关系。
将product
,recipe
,menu
添加到数据库我正在使用JpaRepository<Product(Recipe/Menu), Long>
我创建了管理Menu
的服务:
@Service
public class MenuServiceImpl implements MenuService{
private MenuRepository menuRepository;
private RecipeRepository recipeRepository;
@Override
public List<Menu> getMenus() {
return menuRepository.findAll();
}
@Override
public Menu createMenu(String name) {
Menu menu = new Menu();
menu.setName(name);
menu = menuRepository.saveAndFlush(menu);
return menu;
}
@Override
public Menu getMenu(long id) {
Menu menu = menuRepository.findById(id).get();
return menu;
}
@Override
public Menu addRecipe(long menuId, long recipeId) {
Menu menu = menuRepository.findById(menuId).get();
Recipe recipe = recipeRepository.findById(recipeId).get();
List<Recipe> rs = menu.getRecipes();
rs.add(recipe);
menu.setRecipes(rs);
menu = menuRepository.saveAndFlush(menu);
return menu;
}
}
并写了测试:
@Test
public void shouldCreateSingleMenuAndUpdateAddedTheRecipes() {
Assertions.assertThat(menuRepository.findAll()).size().isEqualTo(0);
Assertions.assertThat(recipeRepository.findAll()).size().isEqualTo(0);
Assertions.assertThat(productRepository.findAll()).size().isEqualTo(0);
Product product = new Product();
product.setName("rod");
product.setCategory(Category.FRUIT);
productRepository.saveAndFlush(product);
Product product2 = new Product();
product2.setName("rod2");
product2.setCategory(Category.NONE);
productRepository.saveAndFlush(product2);
Product product3 = new Product();
product3.setName("rod3");
product3.setCategory(Category.VEGETABLES);
productRepository.saveAndFlush(product3);
Recipe recipe1 = new Recipe();
recipe1.setName("r1");
recipe1.addProduct(product);
recipe1.addProduct(product2);
recipe1.addProduct(product3);
recipe1 = recipeRepository.saveAndFlush(recipe1);
Recipe recipe2 = new Recipe();
recipe2.setName("r2");
recipe2.addProduct(product3);
recipe2 = recipeRepository.saveAndFlush(recipe2);
Recipe recipe3 = new Recipe();
recipe3.setName("r3");
recipe3.addProduct(product3);
recipe3 = recipeRepository.saveAndFlush(recipe3);
Menu menu1 = menuService.createMenu("m1");
menuService.addRecipe(menu1.getId(), recipe1.getId());
menuService.addRecipe(menu1.getId(), recipe2.getId());
Menu menu1AfterAddRecipe = menuService.addRecipe(menu1.getId(), recipe3.getId());
Assertions.assertThat(menu1AfterAddRecipe.getRecipes())
.extracting("name")
.containsOnly(recipe1.getName(), recipe2.getName());
List<Menu> menus = menuRepository.findAll();
Assertions.assertThat(menus).size().isEqualTo(1);
Menu actualMenu = menus.get(0);
Assertions.assertThat(actualMenu).isNotNull();
Assertions.assertThat(actualMenu.getRecipes()).size().isEqualTo(2);
Assertions.assertThat(actualMenu.getRecipes())
.extracting("name")
.containsOnly(recipe1.getName(), recipe2.getName());
}
当我menuService.addRecipe(menu1.getId(), recipe2.getId());
第一次第二次在表recipe2menu
中进行时,会有单行(recipe_i - menu_id)。但是第二次我有3排(1-1; 1-1; 1-2)。但我只想到2,因为我只增加了两次。当我再次调用menuService.addRecipe(menu1.getId(), recipe2.getId());
时,行将为6(1-1; 1-1; 1-1; 1-1; 1-2; 1-3)。如果我没有将产品添加到配方中,问题就会消失......每次添加单个配方时,配方中的产品越多,recipe2menu
表中的行就越多。
Menu menu1AfterAddRecipe = menuService.addRecipe(menu1.getId(), recipe3.getId());
处的断点:
我正在使用MySql。
有什么想法吗?
非常感谢您的帮助!