0

Я пытаюсь перейти от транзакций, управляемых вручную, к транзакциям на основе аннотаций в приложении Neo4j.Невозможно настроить @Transaction для работы с Spring Data Neo4j

Я подготовил аннотацию на основе конфигурации Spring файла:

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


} 

Я пометил мои репозиториев с @Transactional:

@Transactional 
public interface AstronomicalObjectRepo extends 
    GraphRepository<AstronomicalObject>{ 

} 

Я пометил свои единичные тестовые классы и методы испытаний с @Transactional и прокомментировал старый код, который использовался для ручного управления транзакциями:

@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(); 
    //} 

} 

После этого изменения тесты не проходят. я получаю: org.springframework.dao.InvalidDataAccessApiUsageException: вложенное исключение org.neo4j.graphdb.NotInTransactionException

Я пробовал много разных вещей (явно именование менеджер транзакций в @Transactional аннотации, изменяя режим в @EnableTransactionManagment .. .), ничего не помогло.

Будем очень благодарны за понимание того, что я делаю неправильно.

Заранее благодарен!

+0

Где вы заявляете свое управление транзакциями и источник данных ??? –

+0

Класс Neo4jConfiguration, который я продюсирую, выполняет большую часть работы. Он создает компонент «neo4jTransactionManager», который я использую в моем методе «annotationDrivenTransactionManager», чтобы точно определить его как мой менеджер tx по умолчанию (хотя @EnableTransactionManagement должен иметь возможность обнаружить его сам по себе, согласно документам). Я сам определяю bean-файл "graphDatabaseService". Это встроенная база данных графиков neo4j. Он работает правильно, если транзакции управляются вручную. – cichystefan

+0

Почему бы вам не поставить полный код внутри этого класса, а не те круглые скобки, которые у вас есть ... Прямо сейчас все, что мы можем видеть, это аннотации ... И не полезно изолировать проблему –

ответ

1

Я нашел причину ... SDN не поддерживает новейшие Neo4j в условиях транзакции. Я считаю, что это связано с тем, что SpringTransactionManager в neo4j-kernel ушел в версии 2.2+, но не на 100% уверен.

На GitHub мы можем видеть, что 7 часов назад изменение было сделано, чтобы исправить это: https://github.com/spring-projects/spring-data-neo4j/blob/master/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/config/JtaTransactionManagerFactoryBean.java

Быстрое исправление, работал для меня было переопределить метод neo4jTransactionManager из Neo4jConfiguration в моей конфигурации, используя класс Neo4jEmbeddedTransactionManager:

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

    return new JtaTransactionManager(userTransaction, newTxMgr); 
} 
Смежные вопросы