【问题标题】:Due Transaction propagation unable autowired component由于事务传播无法自动装配组件
【发布时间】:2014-06-10 20:44:30
【问题描述】:

我开始使用 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 中,自然它应该从事务上下文运行以将 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;
    }

正如我所提到的,我认为我唯一需要做的就是创建一个新事务(也许使用 propagation=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 吗?

【问题讨论】:

    标签: java spring transactions entitymanager


    【解决方案1】:

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

    【讨论】:

    • 我添加了 TransactionConfiguration 和 Transactional 注释进行测试,但自动装配的 GrantingOfLoanSagaManager 仍然失败
    • 您是否从组件中删除了限定符。另外,为什么要自动装配实现类而不是接口?在您的测试课程中,您可能应该像@Autowired private SagaManager sagaManager; 那样进行接线。在测试类中由构造函数自动装配也不是很干净。在字段上使用它。
    猜你喜欢
    • 1970-01-01
    • 2018-06-06
    • 2018-06-01
    • 2014-11-26
    • 2016-01-21
    • 1970-01-01
    • 2018-11-02
    • 1970-01-01
    相关资源
    最近更新 更多