如何让 Spring Data Neo4j 和 Spring Data JPA 协同工作? [英] How to get Spring Data Neo4j and Spring Data JPA to work together?
问题描述
我有一个应用程序,它使用 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
.
我从 JpaConfig
和 neo4j.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屋!