Cannot configure @Transaction to work with Spring Data Neo4j

匿名 (未验证) 提交于 2019-12-03 01:45:01

问题:

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!

回答1:

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 ); } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!