事务方法抛出 "no transactional entityManager available"
transactional method throwing "no transactional entityManager available"
我有一个定义为@transactional 的方法。事实上,我有一个方法调用一个方法调用一个方法,所有三个都是@transactional。事务逻辑工作正常,直到我将一些方法提取到抽象 class 中以进行一些代码重用,这似乎以某种方式破坏了我的逻辑。
交易方法来自摘要class,这里是相关部分的部分片段(我必须手工重写,所以请原谅我的拼写错误):
public abstract class ReadWriteService<ReadEntityTempalte extends IEntity, WriteEntityTemplate extends IEntity>
//extends jpaRepository, created using @enableJpaRepositories
private searchRepository<WriteEntityTemplate, String> writeRepository;
@PersistenceContext
private EntityManager em;
@transactional
public ReadEntityTemplate save(final WriteEntityTemplate entity){
if(entity == null) return null;
WriteEntityTemplate returnValue = writeRepository_.save(entity);
postSave(returnValue); //checks our security logic
flush();
ReadEntityTemplate returnEntity = find(returnValue.getId());
//required to detect changes made to the view by our save
em.refresh(returnEntity);
}
这样写是因为我们使用的是视图,所以return值可能会在find()中修改到视图中。这种逻辑在过去有效,并且仍然适用于许多调用。
失败的方法是:
@Override
@transational
public void configure(EntityFileConfig config) throws ClassNotFoundException{
//load config from file
for(EntityConfig entityConfig: entityConfigs){
EntityType entityType=EntityTypeService_.find(entityConfig.getKey());
if(entityType==null){
entityType = EntityType.createByRequiredFields(entityConfig.getKey());
}
//update entityType to reflect config file.
entityType = entityTypeService_.save(entityType);
for(String permissionName: entityConfig.getPermissions()){
if(!entityTypeService_.hasPermission(entityType, permissionName)){
Permission permission = permissionSetup.getPermission(permissionName);
if(permission!=null)
//fails on below lines
permissionService._.addPermission(entityType, permission);
}
}
}
}
entityTypeService 和 permissionService 都扩展了上面的抽象class,并使用相同的保存方法而没有改变,addPermissions 是一个 forloop,在每个权限上调用保存。
entityTypeService 有效,但permissionService 失败。当调用权限服务时,如果我这样做 em.isTransactionalEntity 它 returns false.
所有@transactional 注释都使用 spring 注释,而不是 javax 注释。
实际上,似乎有一些权限会保存而其他权限不会,几乎就好像它是不确定的,但这可能很简单,因为修改了一个已经有一些值的数据库文件设置,因此第一次不需要 运行 一些逻辑。
我已经摸索了很多,但还不能确定是什么原因导致我的交易结束。我原以为可能是@persistenceContext,因为 JPARepos 通过不同的方法获取它们的 entityManager,然后使用 @persistenceContext 自动装配,但如果是这样,一切都会失败吗?
任何帮助将不胜感激,我对这个问题的原因感到很困惑。
假设您在 @Configuration
class 上启用了 @EnableTransactionManagement
。
由于您没有在 @Transaction
上设置任何传播,因此默认值为 Required
。这意味着所有方法都必须是事务的一部分。由于您的抽象方法之一不是 @Transactional
的一部分,因此出现错误。
For more information on Spring Transactions.
注:图片取自上方link。
我有一个定义为@transactional 的方法。事实上,我有一个方法调用一个方法调用一个方法,所有三个都是@transactional。事务逻辑工作正常,直到我将一些方法提取到抽象 class 中以进行一些代码重用,这似乎以某种方式破坏了我的逻辑。
交易方法来自摘要class,这里是相关部分的部分片段(我必须手工重写,所以请原谅我的拼写错误):
public abstract class ReadWriteService<ReadEntityTempalte extends IEntity, WriteEntityTemplate extends IEntity>
//extends jpaRepository, created using @enableJpaRepositories
private searchRepository<WriteEntityTemplate, String> writeRepository;
@PersistenceContext
private EntityManager em;
@transactional
public ReadEntityTemplate save(final WriteEntityTemplate entity){
if(entity == null) return null;
WriteEntityTemplate returnValue = writeRepository_.save(entity);
postSave(returnValue); //checks our security logic
flush();
ReadEntityTemplate returnEntity = find(returnValue.getId());
//required to detect changes made to the view by our save
em.refresh(returnEntity);
}
这样写是因为我们使用的是视图,所以return值可能会在find()中修改到视图中。这种逻辑在过去有效,并且仍然适用于许多调用。
失败的方法是:
@Override
@transational
public void configure(EntityFileConfig config) throws ClassNotFoundException{
//load config from file
for(EntityConfig entityConfig: entityConfigs){
EntityType entityType=EntityTypeService_.find(entityConfig.getKey());
if(entityType==null){
entityType = EntityType.createByRequiredFields(entityConfig.getKey());
}
//update entityType to reflect config file.
entityType = entityTypeService_.save(entityType);
for(String permissionName: entityConfig.getPermissions()){
if(!entityTypeService_.hasPermission(entityType, permissionName)){
Permission permission = permissionSetup.getPermission(permissionName);
if(permission!=null)
//fails on below lines
permissionService._.addPermission(entityType, permission);
}
}
}
}
entityTypeService 和 permissionService 都扩展了上面的抽象class,并使用相同的保存方法而没有改变,addPermissions 是一个 forloop,在每个权限上调用保存。
entityTypeService 有效,但permissionService 失败。当调用权限服务时,如果我这样做 em.isTransactionalEntity 它 returns false.
所有@transactional 注释都使用 spring 注释,而不是 javax 注释。
实际上,似乎有一些权限会保存而其他权限不会,几乎就好像它是不确定的,但这可能很简单,因为修改了一个已经有一些值的数据库文件设置,因此第一次不需要 运行 一些逻辑。
我已经摸索了很多,但还不能确定是什么原因导致我的交易结束。我原以为可能是@persistenceContext,因为 JPARepos 通过不同的方法获取它们的 entityManager,然后使用 @persistenceContext 自动装配,但如果是这样,一切都会失败吗?
任何帮助将不胜感激,我对这个问题的原因感到很困惑。
假设您在 @Configuration
class 上启用了 @EnableTransactionManagement
。
由于您没有在 @Transaction
上设置任何传播,因此默认值为 Required
。这意味着所有方法都必须是事务的一部分。由于您的抽象方法之一不是 @Transactional
的一部分,因此出现错误。
For more information on Spring Transactions.
注:图片取自上方link。