如果保存了引用对象,应该更新引用对象吗?

时间:2019-02-14 00:30:06

标签: spring spring-boot jpa spring-data-jpa

想象一下以下情况:我们有两个数据库表,即 Tenant House 。租户使用@ManyToOne映射引用房屋。

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:问题是不是,我是否一开始就应该全部保存房子以避免这种情况。这是关于更好地了解对象的管理方式。

---但是您也可以告诉我,作为一种常见的做法,我是否应该先更新所有内容并保存到最后?

1 个答案:

答案 0 :(得分:1)

关键问题是housetenant已经被管理的实体吗?

如果是(因为它们被装入了仍在运行的同一个事务中),则涉及的所有House实例都相同,并且您无需在{{1}中设置house }。 但是在那种情况下,您甚至都不需要调用save。

如果它们是分离的实例,是的,您需要致电tenant。 没有它,您将获得异常或覆盖对tenant.setHouse(house);的更改,具体取决于您在关系上的级联设置。

执行所有这些操作的首选方法是:

一次交易内:

  • 加载实体
  • 根据需要对其进行操作
  • 提交交易

JPA将跟踪对实体的更改并将其刷新到数据库,然后才真正提交数据库事务。