代码之家  ›  专栏  ›  技术社区  ›  en Peris

CrudRepository不删除具有关系的对象

  •  4
  • en Peris  · 技术社区  · 6 年前

    @Repository
    public interface MenuRepository extends CrudRepository<Menu, Long> {
    ..
    }
    

    @Service
    @Transactional(readOnly = true)
    public class MenuService {
    
         @Autowired
         protected MenuRepository menuRepository;
    
         @Transactional
         public void delete (Menu menu) {
             menuRepository.delete  (menu);
         }
         ..
    }
    

    这个JUnit测试:

    @ContextConfiguration(classes={TestSystemConfig.class})
    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = MenuGestApplication.class) 
    public class MenuServiceTests {
    ...
    @Test
        public void testDelete () {
    
            Menu menu = new menu(); 
            menu.setmenuId("bacalla-amb-tomaquet");
            menuService.save(menu);
    
            MenuPrice menuPrice = new menuPrice(menu);
            menuPrice.setPrice((float)20.0);
            menuPriceService.save(menuPrice);
    
            MenuPriceSummary menuPriceSummary = new menuPriceSummary(menu);
            menuPriceSummary.setFortnightlyAvgPrice((float)20.0);
    
            menuPriceSummaryService.save(menuPriceSummary);
    
            menu = menuService.findBymenuId("bacalla-amb-tomaquet");
    
            assertNotNull (menu);
    
            menuService.delete (menu);
    
            menu = menuService.findBymenuId("bacalla-amb-tomaquet");
    
            assertNull (menu);
    
        }
    }
    

    @OneToMany(mappedBy="menu", cascade = CascadeType.ALL,  orphanRemoval = true, fetch=FetchType.LAZY)
        private List<MenuPrice> price;
    

    Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`elcormenu`.`t_menu_price`, CONSTRAINT `FK19d0sljpshu4g8wfhrkqj7j7w` FOREIGN KEY (`menu_id`) REFERENCES `t_menu` (`id`))
    

    菜单类:

    @Entity
    @Table(name="t_menu")
    public class Menu  implements Serializable {
    
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @JsonProperty("id")
        private Long id;    
    
        @JsonProperty("MenuId")
        private String MenuId;
    
        @OneToMany(mappedBy = "Menu", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
        @JsonIgnore
        private Set<MenuPrice> MenuPrice = new HashSet<>();
    
        @OneToOne(mappedBy = "Menu", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
        @JsonIgnore
        private MenuPriceSummary summary;
    ...
    }
    
    4 回复  |  直到 6 年前
        1
  •  3
  •   Jean Marois    6 年前

    您正在使用这两种方法定义菜单和菜单之间的双向关系 @OneToMany @ManyToOne .当你有一个生物定向的关系,你需要设置双方。在测试中,您在menuprice中设置菜单,但不将menuprice添加到菜单的menuprice集合中。包括以下语句 menu.MenuPrice.add(menuPrice); 创建菜单之后。你也不需要多重 save() 既然你已经指定了 Cascade.All .请尝试以下操作:

    public void testDelete () {
    
        Menu menu = new menu(); 
        menu.setmenuId("bacalla-amb-tomaquet");
    
        MenuPrice menuPrice = new menuPrice(menu);
        menuPrice.setPrice((float)20.0);
    
        // Not needed
        // menuPriceService.save(menuPrice);
    
        // Add menuPrice to menu's menuPrice set
        menu.menuPrice.add(menuPrice);
    
        MenuPriceSummary menuPriceSummary = new menuPriceSummary(menu);
        menuPriceSummary.setFortnightlyAvgPrice((float)20.0);
    
        // Set menuPriceSummary in menu        
        menu.summary = menuPriceSummary;
    
        // Not needed
        //menuPriceSummaryService.save(menuPriceSummary);
    
        // Saving menu will save it children too
        menuService.save(menu);
    
        menu = menuService.findBymenuId("bacalla-amb-tomaquet");
    
        assertNotNull (menu);
    
        menuService.delete (menu);
    
        menu = menuService.findBymenuId("bacalla-amb-tomaquet");
    
        assertNull (menu);
    
    }
    

    在5月份的情况下,您不需要双向关系,可以删除 @一个托马尼 但这取决于业务逻辑需要如何导航到子级或通过JPA查询它。

        2
  •  1
  •   en Lopes    6 年前

    确保在子对象中:menuprice、menupricesummary CascadeType.ALL ,有点像

    @OneToMany(mappedBy="menu", cascade = CascadeType.ALL, fetch=FetchType.LAZY)
    private List<MenuPrice> price;
    
        3
  •  0
  •   ice1000    6 年前

    想想看:

    @Transactional(readOnly = true)
    public class MenuService {
    

    但我的主要问题是:你用了什么? @Transactional

        4
  •  0
  •   ner0    6 年前

    尝试删除@transactional( )从 MenuService

    CascadeType https://docs.oracle.com/javaee/6/api/javax/persistence/CascadeType.html