P
P
p-oleg2018-08-20 19:14:40
Java
p-oleg, 2018-08-20 19:14:40

Why doesn't @Transactional work when creating a spring context via GenericXmlApplicationContext?

There is a class

@Repository
@Transactional(readOnly = true)
public class JpaAssetsRepository implements AssetsRepository {
    @Override
    public boolean save(List<Assets> assets) {
        return false;
    }
}

I try to run:
public class MainTest {
    public static void main(String[] args) {
        try (GenericXmlApplicationContext appCtx = new GenericXmlApplicationContext()) {
            appCtx.load("spring/spring-app.xml", "spring/spring-db.xml");
            appCtx.refresh();
            System.out.println("Bean definition names: " + Arrays.toString(appCtx.getBeanDefinitionNames()));
            JpaAssetsRepository rep3 = appCtx.getBean(JpaAssetsRepository.class);
            rep3.save();
        }
    }
}

Code fails with error:
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'package_name.repository.jpa.JpaAssetsRepository' available
In spring/spring-app.xml and spring/spring-db .xml has everything you need:
<context:annotation-config/>
<tx:annotation-driven/>
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
          p:entityManagerFactory-ref="entityManagerFactory"/>

If @Transactional(readOnly = true) is removed from the repository, then everything works...

Answer the question

In order to leave comments, you need to log in

1 answer(s)
T
TonyJa, 2018-08-21
@p-oleg

Spring, when it sees it, @Transactionalcreates a proxy on the AssetsRepository interface, which is why it does not find the JpaAssetsRepository. Try doing a lookup using the AssetsRepository interface
rep3 = appCtx.getBean( AssetsRepository .class )

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question