小编典典

如何使Spring Data Neo4j和Spring Data JPA协同工作?

java

我有一个应用程序,它使用MySQL和通过REST的Neo4j服务器版本执行一些批处理作业。

我无法弄清楚如何使它们正确地协同工作:我可以使它们两个同时工作,但不能同时工作。我发现的帖子并非特定于Neo4j的服务器版本,也许就是问题所在,因为其他一切对我来说似乎都不错。

我的配置:

JpaConfig

@Configuration
@EnableTransactionManagement(order=Ordered.HIGHEST_PRECEDENCE)
@PropertySource("META-INF/database.properties")
@ImportResource("classpath*:META-INF/repository.xml")
public class JpaConfig {
@Autowired
Environment env;

@Bean(destroyMethod = "close")
public DataSource dataSource() {
    DataSource dataSource = new DataSource();
    dataSource.setDriverClassName(env.getProperty("database.driverClassName"));
    dataSource.setUrl(env.getProperty("database.url"));
    dataSource.setUsername(env.getProperty("database.username"));
    dataSource.setPassword(env.getProperty("database.password"));
    dataSource.setTestOnBorrow(true);
    dataSource.setTestOnReturn(true);
    dataSource.setTestWhileIdle(true);
    dataSource.setTimeBetweenEvictionRunsMillis(1800000);
    dataSource.setNumTestsPerEvictionRun(3);
    dataSource.setMinEvictableIdleTimeMillis(1800000);
    dataSource.setValidationQuery("SELECT 1");
    return dataSource;
}

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
    LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
    entityManagerFactory.setDataSource(dataSource());
    entityManagerFactory.setPackagesToScan("it.smartblue.mcba.domain");
    entityManagerFactory.setJpaDialect(new HibernateJpaDialect());
    Map<String, String> jpaProperties = new HashMap<>();
    jpaProperties.put("hibernate.connection.charSet", "UTF-8");
    jpaProperties.put("hibernate.ejb.naming_strategy", "org.hibernate.cfg.EJB3NamingStrategy");
    jpaProperties.put("hibernate.bytecode.provider", "javassist");
    jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
    entityManagerFactory.setJpaPropertyMap(jpaProperties);
    entityManagerFactory.setPersistenceProvider(new HibernatePersistence());
    return entityManagerFactory;
}

@Bean
public PlatformTransactionManager transactionManager() {
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
    return transactionManager;
}

@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
    return new PersistenceExceptionTranslationPostProcessor();
}
}

Neo4j.xml

<!-- neo4j configuration -->
<neo4j:config graphDatabaseService="graphDatabaseService" entityManagerFactory="entityManagerFactory"/>
<bean id="graphDatabaseService" class="org.springframework.data.neo4j.rest.SpringRestGraphDatabase">
    <constructor-arg index="0" value="http://192.168.11.186:7474/db/data" />
</bean>
<neo4j:repositories base-package="it.smartblue.mcba.neo4j.repository" />

通过这种配置,Mysql可以完美工作,但是Neo4j不会将任何属性保存到它创建的节点上。

如果删除属性entityManagerFactory="entityManagerFactory"Neo4j可以工作,但无法写入MySQL。

我的服务方法用@Transactional或注释@Neo4jTransactional,不能同时使用。

在我发现org.springframework.data.neo4j.rest.SpringRestGraphDatabasegraphDatabaseServicebean
的类中:

@Override
public Transaction beginTx() {
    // return super.beginTx();
    return new NullTransaction();
}

@Override
public TransactionManager getTxManager() {
    return new NullTransactionManager();
}

也许这是一个正在进行的工作?也许我想念某事…

我正在使用Spring 3.1.2,Hibernate 4.1.4。这是我的pom.xml的一部分。

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-jpa</artifactId>
    <version>1.2.0.RC1</version>
</dependency> 
  <!-- Neo4j dependencies -->
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-neo4j</artifactId>
        <version>2.1.0.RC4</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-neo4j-rest</artifactId>
        <version>2.1.0.RC4</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-neo4j-cross-store</artifactId>
        <version>2.1.0.RC4</version>
    </dependency>

阅读 551

收藏
2020-11-26

共1个答案

小编典典

终于我做到了。

不再有两个不同的transactionManager,现在只有一个ChainedTransactionManager

我从JpaConfigneo4j.xml文件中删除了transactionManager bean ,并添加了以下Neo4jConfig

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.neo4j.config.EnableNeo4jRepositories;
import org.springframework.data.neo4j.config.JtaTransactionManagerFactoryBean;
import org.springframework.data.neo4j.config.Neo4jConfiguration;
import org.springframework.data.neo4j.rest.SpringRestGraphDatabase;
import org.springframework.data.neo4j.transaction.ChainedTransactionManager;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;

@EnableNeo4jRepositories(basePackages = { "it.smartblue.mcba.neo4j.repository" })
@Configuration
public class Neo4jConfig extends Neo4jConfiguration {

    @Autowired
    LocalContainerEntityManagerFactoryBean entityManagerFactory;

    @Bean
    public SpringRestGraphDatabase graphDatabaseService() {
        return new SpringRestGraphDatabase("http://192.168.11.186:7474/db/data");
    }

    @Override
    @Bean(name = "transactionManager")
    public PlatformTransactionManager neo4jTransactionManager() throws Exception {
        return new ChainedTransactionManager(new JpaTransactionManager(entityManagerFactory.getObject()),
                new JtaTransactionManagerFactoryBean(graphDatabaseService()).getObject());
    }
}

现在我只能在方法上使用@Transactional注释

2020-11-26