【问题标题】:Hibernate @Transactional not starting transactionHibernate @Transactional 未启动事务
【发布时间】:2012-04-10 10:17:25
【问题描述】:

我有一个使用 Hibernate 的 Web 应用程序,我正在尝试持久化一些数据,但尽管使用了 @Transactional 注释,但它未能在事务中持久化。

我的服务类如下:

@Service("profileService")
public class ProfileService {
    private EntityManager entityManager;

    @Autowired
    private AccountService accountService;

    @Autowired
    private ProfileDAOImpl profileDao;

    @PersistenceContext
    public void setEntityManager(EntityManager em) {
        this.entityManager = em;
    }

    @Transactional
    public void addConnectionToAccount(SocialConnection sc) {
        entityManager.persist(sc);
    }

}

addConnectionToAccount() 方法是从另一个 Spring bean 以普通方法调用的,并且 ProfileService 类当前正在那里注入:

public class HibernateConnectionRepository implements ConnectionRepository {

    @Inject
    private ProfileService profileService;

    @Override
    @Transactional
    public void addConnection(SocialConnection sc) {
        try {
            profileService.addConnectionToAccount(accountId, sc);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

我尝试将@Transactional 注释放在调用方法上,但徒劳无功。

以前我遇到过这样的问题,因为被持久化的对象不满足表限制(例如不可为空的列为空),或者因为该方法是从同一个类中调用的,而调用方法不是事务性的,但这里都不是这种情况..

有什么想法吗?它只是默默地失败,日志如下:

2012-03-26 22:25:04,702 [http-bio-8085-exec-9] DEBUG com.mchange.v2.resourcepool.BasicResourcePool - trace com.mchange.v2.resourcepool.BasicResourcePool@1bc25c8 [managed: 3, unused: 2, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@e5b006)
2012-03-26 22:25:04,710 [http-bio-8085-exec-9] DEBUG org.hibernate.SQL - select SEQ_COUNT from SEQUENCE where SEQ_NAME = 'PO_SEQ' for update
2012-03-26 22:25:04,711 [http-bio-8085-exec-9] DEBUG org.hibernate.SQL - update SEQUENCE set SEQ_COUNT = ? where SEQ_COUNT = ? and SEQ_NAME = 'PO_SEQ'
2012-03-26 22:25:04,723 [http-bio-8085-exec-9] DEBUG com.mchange.v2.resourcepool.BasicResourcePool - trace com.mchange.v2.resourcepool.BasicResourcePool@1bc25c8 [managed: 3, unused: 2, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@e5b006)
2012-03-26 22:25:04,723 [http-bio-8085-exec-9] DEBUG org.hibernate.event.internal.AbstractSaveEventListener - Generated identifier: 2200, using strategy: org.hibernate.id.MultipleHiLoPerTableGenerator

更新

还想提一下,HibernateConnectionRepository bean 没有注释,实际上是在 @Configuration 类中配置的(如果这有什么不同?没有使用太多 @Configuration 类)。

创建bean的方法如下:

@Bean
@Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)
public ConnectionRepository connectionRepository() {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    if (authentication == null) {
        throw new IllegalStateException("Unable to get a ConnectionRepository: no user signed in");
    }
    ApplicationUser user = (ApplicationUser) authentication.getPrincipal();
    return usersConnectionRepository().createConnectionRepository(String.valueOf(user.getAccountId()));
}

bean 的作用域是登录用户,但也可以为每个用户创建多次..

【问题讨论】:

    标签: spring hibernate transactions


    【解决方案1】:

    还有一些事情需要注意(尽管您对约束和从同一个 bean 调用有一个良好的开端):

    • <tx:annotation-driven /> 存在于您的 xml 文件中
    • 确定事务没有启动吗?请与TransactionSynchronizationManager.isActualTransactionActive() 联系。这可能是一个不同的问题(与交易无关)

    【讨论】:

    • 是的,有注释驱动的配置(使用 aspectJ 作为模式而不是代理)。我之前曾尝试添加 entityManager.flush();在坚持调用之后,我收到错误“交易未进行” - 但会检查您建议的代码。谢谢 - 会让你知道它是如何工作的
    • 好的,已经使用事务同步管理器进行了检查——绝对没有事务。但是,它变得陌生了..我添加了 entityManager.flush() 只是为了更早地对其进行测试(并得到了无事务错误),然后我删除了刷新调用并在 Eclipse 中清理了项目/重新启动了 tomcat,这是我第一次在应用程序中它设法提交数据(我在数据库中有行来证明它) - 但进一步尝试重新创建功能失败并且无法保留其他任何内容(已尝试重新清理/重新启动等).. 任何知道为什么有时会启动事务,但并非总是如此?
    • 直到我浏览了整个项目,这是我做不到的。但是您提到了 aspectJ - 请尝试使用代理模式。
    • 确实尝试删除 aspectJ,但随后一些标准的自动装配在项目的其他部分开始失败。也许我会用这种方法再试一次。
    • 我已经更新了我的原始问题,其中包含一些关于如何配置调用 bean 的详细信息 - 在 @Configuration 类中处理,不确定这是否有效果?
    【解决方案2】:

    错误是方面未正确触发的问题。

    与此问题相关:Let eclipse use maven to compile/weave my code 使用新版本的 Eclipse 和 M2E 时发生。

    Eclipse clean 没有编织切面,因此没有编织事务注释。它显然间歇性地工作,因为当我进行正常的 maven 全新安装(命令行等)时,编织将完成(Eclipse clean 然后取消编织,所以如果我做了 maven clean install 然后 eclipse 重新构建它会不工作)。

    我通过在 Eclipse 中将 AspectJ 构建器添加到我的项目中来解决此问题,现在当我自动运行 clean/build 时,它会正确编织它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-18
      • 1970-01-01
      相关资源
      最近更新 更多