cichystefan
cichystefan

Reputation: 328

Cannot configure @Transaction to work with Spring Data Neo4j

I'm trying to move away from manually-managed transactions to annotation based transactions in my Neo4j application.

I've prepared annotation-based Spring configuration file:

@Configuration
@EnableNeo4jRepositories("xxx.yyy.neo4jplanetspersistence.repositories")
@ComponentScan(basePackages = "xxx.yyy")
@EnableTransactionManagement
public class SpringDataConfiguration extends Neo4jConfiguration      
    implements TransactionManagementConfigurer{

public SpringDataConfiguration() {
    super();
    setBasePackage(new String[] {"xxx.yyy.neo4jplanetspojos"});
}

@Bean
public GraphDBFactory graphDBFactory(){
    GraphDBFactory graphDBFactory = new GraphDBFactory();

    return graphDBFactory;
}

@Bean
public GraphDatabaseService graphDatabaseService() {
    return graphDBFactory().getTestGraphDB(); //new GraphDatabaseFactory().newEmbeddedDatabase inside
}   

@Override
public PlatformTransactionManager annotationDrivenTransactionManager() {
    return neo4jTransactionManager(graphDatabaseService());
}  


}

I've marked my repositories with @Transactional:

@Transactional
public interface AstronomicalObjectRepo extends   
  GraphRepository<AstronomicalObject>{

}

I've marked my unit test classes and test methods with @Transactional and commented old code that used to manually manage transactions:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringDataConfiguration.class}, 
   loader = AnnotationConfigContextLoader.class)
@Transactional
public class AstronomicalObjectRepoTest {

@Autowired
private AstronomicalObjectRepo repo;


@Autowired
private Neo4jTemplate neo4jTemplate;   

(...)

@Test @Transactional
public void testSaveAndGet() {
   //try (Transaction tx =   
   //neo4jTemplate.getGraphDatabaseService().beginTx()) {


        AstronomicalObject ceres = new AstronomicalObject("Ceres", 
           1.8986e27, 142984000, 9.925);
        repo.save(ceres); //<- BANG! Exception here


        (...)

        //tx.success();
    //}

}

After that change the tests do not pass. I receive: org.springframework.dao.InvalidDataAccessApiUsageException: nested exception is org.neo4j.graphdb.NotInTransactionException

I have tried many different things (explicitly naming transaction manager in @Transactional annotation, changing mode in @EnableTransactionManagment...), nothing helped.

Will be very grateful for a clue about what I'm doing wrong.

Thanks in advance!

Upvotes: 0

Views: 774

Answers (1)

cichystefan
cichystefan

Reputation: 328

I found the reason... SDN does not support newest Neo4j in the terms of transaction. I believe it is because SpringTransactionManager in neo4j-kernel has gone in 2.2+ releases, but not 100% sure.

On github we can see that 7 hours ago the change was made to fix it: https://github.com/spring-projects/spring-data-neo4j/blob/master/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/config/JtaTransactionManagerFactoryBean.java

A quick fix that worked for me was to override neo4jTransactionManager method from Neo4jConfiguration in my configuration, using Neo4jEmbeddedTransactionManager class:

    @Override
public PlatformTransactionManager neo4jTransactionManager(GraphDatabaseService graphDatabaseService) {
    Neo4jEmbeddedTransactionManager newTxMgr = new Neo4jEmbeddedTransactionManager(graphDatabaseService());
    UserTransaction userTransaction = new UserTransactionAdapter( newTxMgr );

    return new JtaTransactionManager( userTransaction, newTxMgr );
}

Upvotes: 1

Related Questions