小编Chr*_*ris的帖子

如何使用spring-boot和JPA持久化包含另一个未持久实体的多个相同实例的新实体?

概述:

我正在构建一个spring-boot应用程序,该应用程序的一部分是从外部REST服务检索一些实体,并将其与数据库中本地保存的实体的先前版本进行比较。

我注射EntityManager@PersistenceContext,并用它来工作与数据库,因为有许多实体类型,类型最初是未知的模块。我可以JpaRepository从工厂获得,但是不同实体类型的数量容易增加,如果可能的话,我宁愿不依赖它。

问题:

当模块检索它不在数据库中的实体时,它将执行一些业务逻辑,然后尝试保留新实体。

Person班,这是有问题的实体之一,包含类型的三个领域Site,这往往持有相同的对象。

当我尝试使用持久保存一个在多个字段中具有Person相同Site对象的新对象时CascadeType.PERSIST,我得到了一个EntityExistsException(请参阅stacktrace(1))。

当我从Site字段中删除CascadeType.PERSIST 并尝试在多个字段中保留Person具有相同Site对象的新对象时,我得到了TransientPropertyValueException(请参见stacktrace(2))。

我想我了解两种例外情况发生的原因:

  • 在第一种情况下,是因为在第一个站点字段被级联持久化之后,它无法在第二个字段中重新持久化。

  • 我认为的第二种情况是因为@Transactional注释正在尝试在不持久化站点实例的情况下刷新事务。

我尝试删除@Transactional注释并自己开始并提交EntityTransaction,但我得到了一个IllegalStateException(请参阅stacktrace(3)),尽管我认为这是可以预期的,因为spring应该自己处理事务本身。

我已经看过类似问题的答案(例如thisthis),但都提出了更改CascadeType的一些变体。

在另一个问题中,有人建议确保该equals()方法正确评估了有问题的实体,因此我在调试器中签入并((Person)newEntity).currentSite.equals(((Person)newEntity).homeSite)评估为true。

如何在多个字段中一致地持久保存/合并具有相同对象的实体?


编辑:我也尝试了级联类型与的各种组合fetch = FetchType.EAGER,但这不会改变它们各自的异常。


编辑2:我尝试使用a JpaRepository而不是使用EntityManager,并且根据我使用的层叠类型有效地获得了相同的异常集。

如果我使用PERSIST,但没有MERGE,我得到一个EntityNotFoundException(见堆栈跟踪(4)),如果我同时使用PERSISTMERGE我得到一个InvalidDataAccessApiUsageException`(见堆栈跟踪(5))。


人: …

java jpa cascade entitymanager persist

3
推荐指数
1
解决办法
1214
查看次数

标签 统计

cascade ×1

entitymanager ×1

java ×1

jpa ×1

persist ×1