我有以下设置: 春天 - > JPA - > Hibernate - > PostgreSQL的
我已经创建了一个服务层,它提供了一些“@Transactional”方法来插入数据。数据在具体情况下是必须连接到类别实体(识别关系)和一些图片实体(非识别关系)的人员实体。
由于我必须提供导入器,因此我创建了一个方法(也是@Transactional)来导入csv文件。此方法首先尝试插入类别(使用从服务层调用的DAO中使用的em.persist()可以很好地工作)。然后我添加一个新的人,它连接到我之前添加的类别(类别加载,就像它已经在数据库中一样 - > HQL查询),这也适用于该类别在正在运行的事务中是持久的。 person实体还使用em.persist()来持久化事务。
现在我创建图片实体并将它们连接到person实体。在连接它们之后,我也保存了这个人,但由于它已经存在于事务中,所以我使用了em.merge()。这里我得到一个“EntityNotFoundException()”,因为hibernate(或jpa)无法从第一步加载类别(它有一个正确的id,但似乎它看不到事务)......
所有三个方法insertCategory(),insertPerson()和addPicture()也被声明为@Transaction,因为它们在正常用例中单独使用。也许这个问题与嵌套的Transaction有关,但它似乎与em.merge()有关,因为em.persist()运行良好。
em是一个从spring注入的EntityManager。
任何想法出了什么问题?
问候本
答案 0 :(得分:1)
如果使用代理(事务处理的Spring默认值),则在类 中调用方法时,将忽略@Transactional注释。以下内容不起作用:
@Transactional
public void doStuff() {
this.doSomeOtherStuff();
}
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void doSomeOtherStuff() {
// do some more db work here.
}
如果您确实这样做,您有两种选择:
您可以在Spring文档here中了解更多相关信息。
在代理模式(默认设置)下,只拦截通过代理进入的外部方法调用。这意味着实际上,自调用目标对象中的一个方法调用目标对象的另一个方法,即使被调用的方法用@Transactional标记,也不会在运行时导致实际的事务。