我已经开始使用Guice方法级事务,如here所述。我有一条消息,如
@Inject
private EntityManager entityManager;
@Transactional
public UserSession createSession(User user, String browser) {
UserSession session = new UserSession(user, browser);
entityManager.persist(session);
}
从简短描述中我认为应该足够了。但是我得到一个错误,因为没有启动任何事务。只有当我自己开始并提交它时,它才有效。
对象由Guice在初始化程序中的应用程序开始时创建。每个请求都使用相同的实例。
为什么不起作用?
答案 0 :(得分:6)
@Transactional
方法注释通过AOP
工作,其中Guice通过创建拦截那些带注释的方法调用的代理对象来满足Foo
的请求,并且(可选地)将它们转发到实际宾语。确保满足以下条件:
您已通过Guice使用@Transactional
方法创建了对象,因为Guice否则将无法提供代理。
类和方法都没有标记final
,因为AOP不能轻易覆盖它们。
您已安装JpaPersistModule或其他形式的PersistModule。请注意,该源代码实际上是将MethodInterceptor
绑定到@Transactional
注释的内容。
如果这不完全符合您的需求,请记住您始终可以使用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获取。
所以我创建了BusinessLogicProvider
(extends 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都需要创建一个新的。