0

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

Shivam Sinha
  • 4,924
  • 7
  • 43
  • 65
  • 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 Mar 04 '15 at 10:17
  • M.Deinum For Spring to enable any transaction management within your application you are required to have either `@EnableTransactionManagement` or . The specific transactionManager that you actually use is independent to this. Hence you need both `@EnableTransactionManagement` and a TransactionManager bean. Further info: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/transaction/annotation/EnableTransactionManagement.html – Shivam Sinha Mar 04 '15 at 15:25
  • 1
    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 Mar 04 '15 at 15:40
  • Agreed but spring boot also allows you you be explicit about the services you want from the container. When I enable the transaction management via `@EnableTransactionManagement` spring boot automatically switches off the AutoConfigured: `DataSourceTransactionManagerAutoConfiguration#transactionManager`, which is evident in the Spring Boot AutoConfiguration Report. – Shivam Sinha Mar 04 '15 at 15:50
  • 1
    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 Mar 05 '15 at 06:56
  • 1
    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... " http://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-auto-configuration.html – Shivam Sinha Mar 06 '15 at 01:41

1 Answers1

0

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.

Shivam Sinha
  • 4,924
  • 7
  • 43
  • 65
  • What did you then use to replace the Neo4jConfiguration class you stopped using ? – Stephane Sep 01 '15 at 12:58
  • 1
    I just copied Neo4jConfiguration.java and removed the method: neo4jTransactionManager() http://pastebin.com/tvSs7ViL – Shivam Sinha Sep 01 '15 at 14:51
  • Isn't there some alternative to this class copy ? As a noob, there are a few questions hanging in me: Can Neo4J reuse the Spring Data transaction manager ? Or should Neo4J use its own transaction manager ? Is it possible to have a transaction spanning the two data stores (JPA & Neo4J) ? – Stephane Sep 01 '15 at 15:36
  • 1
    Will respond to your question in approx 8hrs. Staring work :) – Shivam Sinha Sep 01 '15 at 15:44
  • As explained in 22.13 of http://docs.spring.io/spring-data/neo4j/docs/current/reference/pdf/spring-data-neo4j-reference.pdf I'd like to "have Neo4j participate in the externally configured transaction manager using the Spring support in Neo4j by enabling the configuration parameter for your graph database. Neo4j will then use Spring’s transaction manager instead of its own." with my goal being http://stackoverflow.com/questions/32296676/tests-fail-with-a-transactionrequiredexception-no-transaction-is-in-progress-ex?noredirect=1#comment52472384_32296676 – Stephane Sep 01 '15 at 16:27