gpt4 book ai didi

java - CrudRepository 不会删除具有关系的对象

转载 作者:搜寻专家 更新时间:2023-11-01 02:36:17 25 4
gpt4 key购买 nike

我有一个基本的 SpringBoot 应用程序。使用 Spring Initializer、JPA、嵌入式 Tomcat、Thymeleaf 模板引擎,并打包为可执行 JAR 文件。我创建了这个 Repository 类:

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

}
}

但是 Junit 失败了,因为对象没有被删除,也没有抛出异常!

按照建议,我在属性中有这个..

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

最佳答案

您正在使用 @OneToMany@ManyToOne 定义 Menu 和 MenuPrice 之间的双向关系。当你有双向关系时,你需要设置双方。在测试中,您在 MenuPrice 中设置 Menu,但没有将 MenuPrice 添加到 Menu 的 MenuPrice Set 中。在创建 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);

}

在许多情况下,您不需要双向关系并且可以删除 @OneToMany,但这取决于您的业务逻辑需要如何导航到子项或通过 JPA 查询它。

关于java - CrudRepository 不会删除具有关系的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50818106/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com