我有一个应用程序,它使用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。
entityManagerFactory="entityManagerFactory"
我的服务方法用@Transactional或注释@Neo4jTransactional,不能同时使用。
@Transactional
@Neo4jTransactional
在我发现org.springframework.data.neo4j.rest.SpringRestGraphDatabase的graphDatabaseServicebean 的类中:
org.springframework.data.neo4j.rest.SpringRestGraphDatabase
graphDatabaseService
@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>
终于我做到了。
不再有两个不同的transactionManager,现在只有一个ChainedTransactionManager。
ChainedTransactionManager
我从JpaConfig和neo4j.xml文件中删除了transactionManager bean ,并添加了以下Neo4jConfig
neo4j.xml
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注释