Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring/JPA/Hibernate/PostgreSQL在嵌套事务中抛出EntityNotFoundException_Hibernate_Spring_Postgresql_Jpa - Fatal编程技术网

Spring/JPA/Hibernate/PostgreSQL在嵌套事务中抛出EntityNotFoundException

Spring/JPA/Hibernate/PostgreSQL在嵌套事务中抛出EntityNotFoundException,hibernate,spring,postgresql,jpa,Hibernate,Spring,Postgresql,Jpa,我有以下设置: Spring->JPA->Hibernate->PostgreSQL 我创建了一个服务层,它提供了一些插入数据的“@Transactional”方法。在具体情况下,数据是必须连接到类别实体(标识关系)和一些图片实体(非标识关系)的个人实体 由于我必须提供一个导入器,所以我创建了一个方法(也是@Transactional)来导入csv文件。此方法首先尝试插入类别(使用服务层调用的DAO中使用的em.persist()可以很好地工作)。然后我添加了一个新的人员,该人员将连接到我之前添

我有以下设置: Spring->JPA->Hibernate->PostgreSQL

我创建了一个服务层,它提供了一些插入数据的“@Transactional”方法。在具体情况下,数据是必须连接到类别实体(标识关系)和一些图片实体(非标识关系)的个人实体

由于我必须提供一个导入器,所以我创建了一个方法(也是@Transactional)来导入csv文件。此方法首先尝试插入类别(使用服务层调用的DAO中使用的em.persist()可以很好地工作)。然后我添加了一个新的人员,该人员将连接到我之前添加的类别(该类别将被加载,就像它已经在数据库->HQL查询中一样),这也可以作为该类别在正在运行的事务中的持久性。person实体还使用em.persist()在事务中持久化

现在我创建图片实体并将它们连接到person实体。在连接它们之后,我还保存了person,但由于它已经保存在事务中,所以我使用em.merge()。这里我得到了一个“EntityNotFoundException()”,因为hibernate(或jpa)无法从第一步加载类别(它有一个正确的id,但似乎看不到事务)

所有三个方法insertCategory()、insertPerson()和addPicture()也声明为@Transaction,因为它们在正常用例中单独使用。问题可能与嵌套事务有关,但更可能与em.merge()有关,因为em.persist()运行良好

em是一个从spring注入的实体管理器

你知道怎么回事吗

如果您使用代理(事务处理的Spring默认设置),则在类中调用方法时,@Transactional注释将被忽略。以下操作将不起作用:

@Transactional
public void doStuff() {
  this.doSomeOtherStuff();
}

@Transactional(propagation=Propagation.REQUIRES_NEW)
public void doSomeOtherStuff() {
  // do some more db work here.
}
如果您确实在这样做,您有两个选择:

  • 使用AspectJ而不是代理。这需要一点学习曲线
  • 将需要事务的方法移动到另一个类中
  • 您可以在Spring文档中阅读更多关于这方面的内容

    在代理模式(这是默认模式)下,只截获通过代理传入的外部方法调用。这意味着自调用,实际上是目标对象内调用目标对象另一个方法的方法,即使调用的方法标记为@Transactional,在运行时也不会导致实际事务