到期事务传播无法自动装配组件

时间:2014-06-10 20:44:30

标签: java spring transactions entitymanager

我开始使用TDD编写跟随代码:

 @Component("GrantingOfLoanSagaManager")
 public class GrantingOfLoanSagaManager implements
    SagaManager {

     private ApplicationContext applicationContext;

     @PersistenceContext
     private EntityManager entityManager;

     public GrantingOfLoanData createNewSagaData(AggregateId id ) {
         GrantingOfLoanData sagaData = new GrantingOfLoanData();
         sagaData.setRequestId(id);
         entityManager.persist(sagaData);
         return sagaData;
    }
 } 

并测试这个SagaManager类:

 @RunWith(SpringJUnit4ClassRunner.class)
 @WebAppConfiguration
 @ContextConfiguration(
    classes = ConfigTest.class)
 public class SagaTest {

     @PersistenceContext
     EntityManager entityManager;

     private ApplicationContext applicationContext;

     private GrantingOfLoanSagaManager sagaManager;

     @Autowired
     public void setApplicationContext(ApplicationContext applicationContext) {
         this.applicationContext = applicationContext;
     }

     @Autowired
     public void setSagaManager(GrantingOfLoanSagaManager sagaManager) {
         this.sagaManager = sagaManager;
     }

     @Test
     @Transactional
     public void onCompleteEventsTriggered(){

     Client client = new Client();
         entityManager.persist(client);

     invokeFromSagaManagerCreateNewSagaData_method(); //some code that invoke via spring createNewSagaData() method in SagaManager
     }
}

但是后来我遇到了这个createNewSagaData()方法的一些问题,因为它使用EntityManager来保存DB中的对象,当然它应该从Transactional上下文运行以将newSagaData保存在DB中,每个调用createNewSagaData()的方法都应该有@事务性注释并创建新事务。所以我发现它是不兼容的解决方案,我改变了createNewSagaData方法如下:

    @Transactional //Annotation was added
    public GrantingOfLoanData createNewSagaData(AggregateId id ) {
        GrantingOfLoanData sagaData = new GrantingOfLoanData();
        sagaData.setRequestId(id);
        entityManager.persist(sagaData);
        return sagaData;
    }

正如我所提到的,我认为我唯一需要的是创建一个新的交易(可能是传播= REQUIRED_NEW)

但是在那之后我运行unitTests(/ Integration test)时我得到了例外:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.finance.app.core.domain.businessprocess.loangrant.GrantingOfLoanSagaManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

所以我不知道如何解决它。我应该对每个调用EntityManager的外部方法使用@Transactional吗?

1 个答案:

答案 0 :(得分:1)

Bean名称必须以小写字母开头,如果你将它们用作这样的限定符:@Component("grantingOfLoanSagaManager"),但如果不需要,我就不会使用限定符。 Autowire按类型扫描正确的bean。您还应该使用@Transactional@TransactionConfiguration

标记整个测试类