【发布时间】:2019-07-07 22:56:25
【问题描述】:
想象以下情况:我们有两个数据库表,Tenant 和 House。租户使用 @ManyToOne 映射引用 House。
Tenant tenant = tenantRepository.findById(id).orElseThrow();
House house = tenant.getHouse();
house.setPrice(340_000);
house = houseRepository.save(house); // A new instance is returned by the CrudRepository::save() method
// TODO Is this necessary for further use?
tenant.setHouse(house);
// Further use...
tenant.setAge(23);
tenant = tenantRepository.save(tenant); // Otherwise it is saved with the old reference where house's ID can be null?
...
是否需要将租户更新为 House 的新引用?
编辑:为澄清起见,您可以假设实体在上述代码之前立即加载(因此处于托管状态)。并且因为这个“事务”是 Spring @RequestMapping 函数的一部分,所以事务将在它的末尾隐式提交。
编辑2:问题是不我是否应该在一开始就拯救房子以避免这种情况。这是为了更好地理解对象的管理方式。
---但是你也可以告诉我,我应该先更新所有内容,然后保存,作为一种常见做法吗?子>
【问题讨论】:
-
A new instance is returned ...只是部分正确。应该是The saved instance is returned ...。然后,the saved instance依赖于 JPA 提供程序。例如,Hibernate 返回传递给save方法的相同对象(直到当前版本),而其他提供者可能完全返回不同的对象。这就是 JPA 规范建议使用从save调用返回的实例的原因。如果您想与提供者无关或与 Hibernate 以外的任何东西相关联,则应在保存house后调用tenant.setHouse(house)。 -
JPA 规范实际上是指
persist和merge方法。 JPA API 中没有save -
很抱歉,为什么不发布理解您的问题所需的完整代码呢?在不知道这些关心现有实体还是新实体的情况下,没有人可以给出明智的答案
-
@BillyFrost 我说的是 Spring Data JPA 和 CrudRepository,它们是 JPA 之上的另一层。
-
显然 ... JPA 规范中没有提到。
标签: spring spring-boot jpa spring-data-jpa