0
votes

I think i'm missing something obvious. Iam trying to make a entity persist into a database via a JUnit Test case, however it doesnt seem to be persisting due to no active transaction.

Configuration:

 @Configuration
    @EnableTransactionManagement
       public class TransactionConfig {

    @Inject 
    private EntityManagerFactory entityMangerFactory;

    @Bean
    public JpaTransactionManager transactionManager(){
        return new JpaTransactionManager(entityMangerFactory);
    }

TestCase:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = { Application.class })
@ActiveProfiles(CommonConstants.SPRING_PROFILE_TEST)
@IntegrationTest
@WebAppConfiguration
public class UserRepositoryTest {

    @Inject
    UserRepository userRepo;

    @Test
    @Rollback(false)
    @Transactional("transactionManager")
    public void addUser() {
        User user = BootstrapDataPopulator.getUser();
        userRepo.save(user);
        System.out.println(user.getId()); //Successfully outputs the id generate by hibernate
        assertNotNull(user.getId());
    }
}

^This test case executed successfully however I do not see any entiites persisted in the database as expected.

When I change the from userRepo.save(user) to userRepo.saveAndFlush(user) I get the following exception:

javax.persistence.TransactionRequiredException: no transaction is in progress
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.checkTransactionNeeded(AbstractEntityManagerImpl.java:1171)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:1332)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

Spring Boot AutoConfiguration Report: http://dumptext.com/YcGaR3Wf

Names of all Spring Beans Initialized: http://dumptext.com/jp9O6l8v

1
Why are you configuring @EnableTransactionManagement and the JpaTransactionManager yourself? Spring Boot does that already for you. Remove your TransactionConfig class I would say... Also it isn't an integration test to remove the @IntegrationTest annotation. - M. Deinum
M.Deinum For Spring to enable any transaction management within your application you are required to have either @EnableTransactionManagement or <tx:*>. The specific transactionManager that you actually use is independent to this. Hence you need both @EnableTransactionManagement and a TransactionManager bean. Further info: docs.spring.io/spring/docs/current/javadoc-api/org/… - Shivam Sinha
For a normal spring application that is correct however that isn't correct for a Spring Boot application as Spring Boot is taking care of that for you... - M. Deinum
The DataSourceTransactionManagerAutoConfiguration has nothing to do with this it would have to be the JPA one. What you are basically doing is using a framework and then trying to not use the features of the framework, seems silly to me. - M. Deinum
Yes my mistake I ment JpaBaseConfiguration#transactionManager not DataSourceTransactionManagerAutoConfiguration. It's not silly at all to only pick certain features u want from a framework. The purpose of spring boot is to get you prototyping applications quickly. I wouldnt recommend having a full running production application using Spring boot auto configure. "Auto-configuration is noninvasive, at any point you can start to define your own configuration... " docs.spring.io/spring-boot/docs/current/reference/html/… - Shivam Sinha

1 Answers

0
votes

I am using Spring Data Neo4j (SDN) in my application as well. SDN comes with a default class Neo4jConfiguration which has:

@Bean(name = {"neo4jTransactionManager","transactionManager"})
@Qualifier("neo4jTransactionManager")
public PlatformTransactionManager neo4jTransactionManager() throws Exception {
    return new JtaTransactionManagerFactoryBean(getGraphDatabaseService()).getObject();
}

The "transactionManager" overrides the bean defined in my TransactionConfig class. Hence the reason no Entity transaction was in progress. I stopped using the SDN class Neo4jConfiguration. This resolved my issue.