我使用JBoss来部署使用CDI和CD的应用程序。 EJB。
“applicationContext.xml”包含JTA数据源连接。
“test-applicationContext.xml”包含RESOURCE_LOCAL数据源连接。
===案例1 ====
我有一个像这样的CDI bean:
@Named
@Transactional
public class EmployeeRoleInserter {
@PersistenceContext(unitName = PersistenceConstants.PERSISTENCE_UNIT)
private EntityManager entityManager;
...
}
和这样的JUnit测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:/test-applicationContext.xml"})
public class EmployeeRoleInserterTest {
@Inject
private EmployeeRoleInserter inserter;
@Test
public void testInsert() {
JUnit测试和事务有效,但JBboss上的部署会产生错误:
Caused by: javax.faces.el.EvaluationException: javax.persistence.TransactionRequiredException: JBAS011469: Transaction is required to perform this operation (either use a transaction or extended persistence context)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:101) [jboss-jsf-api_2.1_spec-2.1.18.Final.jar:2.1.18.Final]
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:101) [jsf-impl-2.1.18-jbossorg-1.jar:]
... 25 more
Caused by: javax.persistence.TransactionRequiredException: JBAS011469: Transaction is required to perform this operation (either use a transaction or extended persistence context)
at org.jboss.as.jpa.container.AbstractEntityManager.transactionIsRequired(AbstractEntityManager.java:692) [jboss-as-jpa-7.2.0.Final.jar:7.2.0.Final]
at org.jboss.as.jpa.container.AbstractEntityManager.persist(AbstractEntityManager.java:562) [jboss-as-jpa-7.2.0.Final.jar:7.2.0.Final]
at com.devinition.policy.employee.registration.EmployeeRoleInserter.insertEmployee(EmployeeRoleInserter.java:52) [classes:]
at com.devinition.policy.employee.registration.EmployeeRoleInserter.insert(EmployeeRoleInserter.java:33) [classes:]
at com.devinition.policy.employee.registration.EmployeeRegistrationController.save(EmployeeRegistrationController.java:68) [classes:]
at com.devinition.policy.employee.registration.EmployeeRegistrationController$Proxy$_$$_WeldClientProxy.save(EmployeeRegistrationController$Proxy$_$$_WeldClientProxy.java) [classes:]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) [rt.jar:1.7.0]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) [rt.jar:1.7.0]
at java.lang.reflect.Method.invoke(Unknown Source) [rt.jar:1.7.0]
at org.apache.el.parser.AstValue.invoke(AstValue.java:258) [jbossweb-7.2.0.Final.jar:7.2.0.Final]
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278) [jbossweb-7.2.0.Final.jar:7.2.0.Final]
at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:39) [weld-core-1.1.10.Final.jar:2012-10-12 10:00]
at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50) [weld-core-1.1.10.Final.jar:2012-10-12 10:00]
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105) [jsf-impl-2.1.18-jbossorg-1.jar:]
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87) [jboss-jsf-api_2.1_spec-2.1.18.Final.jar:2.1.18.Final]
... 26 more
===案例2 ====
EJB bean:
@Stateless
public class EmployeeRoleInserter {
@PersistenceContext(unitName = PersistenceConstants.PERSISTENCE_UNIT)
private EntityManager entityManager;
JUnit测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:/test-applicationContext.xml"})
public class EmployeeRoleInserterTest {
@EJB
private EmployeeRoleInserter inserter;
@Test
public void testInsert() {
测试用例会产生错误:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.devinition.policy.employee.registration.EmployeeRoleInserter] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.ejb.EJB(beanName=, mappedName=, beanInterface=class java.lang.Object, description=, name=, lookup=)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1100)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:960)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:855)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:441)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:419)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$EjbRefElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:687)
at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:150)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:304)
... 26 more
但JBoss上的部署可以很好地处理事务!
===案例3 ===
最后我混合了它们(CDI和EJB):
@Named
@Stateless
@Transactional
public class EmployeeRoleInserter {
@PersistenceContext(unitName = PersistenceConstants.PERSISTENCE_UNIT)
private EntityManager entityManager;
JUnit的
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:/test-applicationContext.xml"})
public class EmployeeRoleInserterTest {
@Inject
private EmployeeRoleInserter inserter;
@Test
public void testInsert() {
JUnit测试和交易运作良好。
JBoss上的部署也可以,但是事务不起作用!我的意思是自动提交就像真的
=> The question is "How can I make it work on both JBoss and JUnit Test???"
答案 0 :(得分:1)
EmployeeRoleInserter
bean中的不要使用类的@Transactional
注释,而是将它用于保存其中对象的方法或者
将CRUD操作放在事务manualy
中,而不是使用@Transaction注释,因为@Transaction puts the whole operations inside one transaction