如何让 Spring Data Neo4j 和 Spring Data JPA 协同工作? [英] How to get Spring Data Neo4j and Spring Data JPA to work together?

查看:30
本文介绍了如何让 Spring Data Neo4j 和 Spring Data JPA 协同工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an application that does some batch jobs using MySQL and, via REST, Neo4j server version.

我不知道如何让它们正确地协同工作:我可以让它们同时工作,但不能同时工作.我发现的帖子并非针对 Neo4j 的服务器版本,也许这就是问题所在,因为我觉得其他一切都没有问题.

I can't figure out how to make them to work together correctly: I can get to make work both of them, but not at the same time. The posts I've found around are not specific to the server version of Neo4j, and maybe that's where the problem is, since everything else seems ok to me.

我的配置:

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 不会将任何属性保存到它创建的节点中.

With this configuration Mysql works perfectly, but Neo4j doesn't save any property to the nodes it creates.

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

If I remove the attribute entityManagerFactory="entityManagerFactory" Neo4j works, but I can't write to MySQL.

我的服务方法使用 @Transactional@Neo4jTransactional 进行注释,而不是同时使用.

My services methods are annotated with @Transactional or @Neo4jTransactional, not both at the same time.

在我发现的 graphDatabaseService bean 的 org.springframework.data.neo4j.rest.SpringRestGraphDatabase 类中:

Inside the class org.springframework.data.neo4j.rest.SpringRestGraphDatabase for the graphDatabaseService bean I've found:

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

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

也许这是一项正在进行的工作?或者我错过了什么......

Maybe it's a work in progress? Or maybe I miss something...

我使用的是 Spring 3.1.2、Hibernate 4.1.4.这是我的 pom.xml 的一部分.

I'm using Spring 3.1.2, Hibernate 4.1.4. Here is part of my 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>

推荐答案

我终于做到了.

现在我只有一个 ChainedTransactionManager,而不是两个不同的 transactionManager.

Instead of having two different transactionManagers, now I have only one ChainedTransactionManager.

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

I removed the transactionManager bean from JpaConfig and the neo4j.xml file, and added the following 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 注释

Now I have to use on my methods only the @Transactional annotation

这篇关于如何让 Spring Data Neo4j 和 Spring Data JPA 协同工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆