Guice @Transactional不会启动交易

时间:2012-12-31 01:31:50

标签: java guice

我已经开始使用Guice方法级事务,如here所述。我有一条消息,如

@Inject
private EntityManager entityManager;

@Transactional
public UserSession createSession(User user, String browser) {
    UserSession session = new UserSession(user, browser);
    entityManager.persist(session);
}

从简短描述中我认为应该足够了。但是我得到一个错误,因为没有启动任何事务。只有当我自己开始并提交它时,它才有效。

对象由Guice在初始化程序中的应用程序开始时创建。每个请求都使用相同的实例。

为什么不起作用?

4 个答案:

答案 0 :(得分:6)

@Transactional方法注释通过AOP工作,其中Guice通过创建拦截那些带注释的方法调用的代理对象来满足Foo的请求,并且(可选地)将它们转发到实际宾语。确保满足以下条件:

  1. 您已通过Guice使用@Transactional方法创建了对象,因为Guice否则将无法提供代理。

  2. 类和方法都没有标记final,因为AOP不能轻易覆盖它们。

  3. 您已安装JpaPersistModule或其他形式的PersistModule。请注意,该源代码实际上是将MethodInterceptor绑定到@Transactional注释的内容。

  4. 如果这不完全符合您的需求,请记住您始终可以使用AOP documentation编写自己的方法拦截器。祝你好运!

答案 1 :(得分:2)

再次检查完所有内容后,它无效。有趣的是它在两者之间起作用,但只有每一次。

经过一些额外的测试后,我发现我需要在每个请求上重新创建类。之前我刚刚在应用程序启动时创建它们。现在看起来效果很好。

感谢您的提示帮助我进一步调查。

答案 2 :(得分:1)

我遇到了与您类似的问题,并通过从@ javax.transaction.Transactional切换到@ com.google.inject.persist.Transactional来解决。显然,Guice-Persist不支持Java Transaction API中的@Transactional注释。

答案 3 :(得分:0)

在以下情况下我遇到了这个问题,所以我想我也会在这里发布我的解决方案:

BusinessLogic需要两个构造函数参数:MyDao,我理论上可以从guice获取,还有一些其他对象,我可以从guice获取。
所以我创建了BusinessLogicProviderextends AbstactProvider),但它不与bind(BusinessLogic.class).toProvider(BusinessLogicProvider)一起使用。 现在,我只需将BusinessLogicProvider绑定为任何guice-served类型:bind(BusinessLogicProvider.class);

在我的BusinessLogicProvider课程中,我现在可以在@Inject上使用private Provider<MyDao> daoProvider;

稍后,在BusinessLogicProvider的{​​{1}}方法中,我可以使用所需的两个参数调用public BusinessLogic get()的构造函数:BusinessLogic和另一个我不能的对象来自guice。

陷阱:daoProvider.get() @Inject private Provider<MyDao> daoProvider; BusinessLogicProvider不属于Provider<MyDao>类型时(但是类型为{{1} }},它不起作用 即使MyDao ed @Inject 来自guice,每次实例化MyDao时,guice都需要创建一个新的。