2017-08-16 89 views
1

我有一个Spring启动neo4j应用程序并希望将用户存储在Neo4j数据库中。我按照说明找到了here。 的Neo4j的配置是这样的:Spring Data Neo4j InvalidDataAccessApiUsageException:此线程的事务不是最新的

@Configuration 
@EnableWebMvc 
@ComponentScan({"eu.bm"}) 
@EnableNeo4jRepositories("eu.bm.repository") 
@EnableTransactionManagement 
public class bmConfiguration extends WebMvcConfigurerAdapter { 

@Bean 
public OpenSessionInViewInterceptor openSessionInViewInterceptor() { 
    OpenSessionInViewInterceptor openSessionInViewInterceptor = 
      new OpenSessionInViewInterceptor(); 
    openSessionInViewInterceptor.setSessionFactory(sessionFactory()); 
    return openSessionInViewInterceptor; 
} 

public void addInterceptors(InterceptorRegistry registry) { 
    registry.addWebRequestInterceptor(openSessionInViewInterceptor()); 
} 

@Bean 
public static SessionFactory sessionFactory() { 
    return new SessionFactory("eu.bm.domain"); 
} 

@Bean 
public Neo4jTransactionManager transactionManager() throws Exception { 
    return new Neo4jTransactionManager(sessionFactory()); 
} 

的用户信息库是这样的:

@Repository 
public interface UserRepository extends GraphRepository<User>{ 

@Query("MATCH (user:User) where user.name={0} return user ") 
User findUser(String username); 

@Query("MATCH (user:User) where user.name={0} delete user ") 
User deleteUser(String username); 

@Query("match (user:User) delete user") 
User deleteAllUsers(); 

} 

我也有这样的用户管理服务设置:

@Component 
public interface UserManagementService { 

List<User> listAll(); 

User save(User user); 

User findUser(String username); 
} 

这也是在这里实现:

@Service 
@Transactional 
public class UserManagementServiceImpl implements UserManagementService { 

private UserRepository userRepository; 

@Autowired 
public UserManagementServiceImpl(UserRepository userRepository) {this.userRepository = userRepository;} 

@Override 
public List<User> listAll() { 
    List<User> users = new ArrayList<>(); 
    userRepository.findAll().forEach(users::add); 
    return users; 
} 

@Override 
public User save(User user) { 
    userRepository.save(user); 
    return user; 
} 

@Override 
public User findUser(String username) { 
    return userRepository.findUser(username); 
} 

我然后这样执行简单的写 - 读测试:

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringBootTest 
public class DatabaseConnectionTest { 

// User 1 
private static final String UNAME1 = "Paul"; 
private static final String EMAIL1 = "[email protected]"; 
private static final String PASSWORD1 = "[email protected]"; 
private static final String USERNAME1 = "paul"; 

@Autowired 
private UserRepository userRepository; 

@Before 
public void setUp() throws Exception { 

    // Clear database before adding new user 
    userRepository.deleteAllUsers(); 

    // Creating user 
    User user = new User(UNAME1, USERNAME1, PASSWORD1, EMAIL1); 
    userRepository.save(user); 
} 

@Test 
public void testPersistence() { 

    Assert.assertEquals(UNAME1, userRepository.findUser(UNAME1).getName()); 
    Assert.assertEquals(USERNAME1, userRepository.findUser(UNAME1).getUsername()); 

} 

的上述结果是这样的错误:

2017-08-16 14:59:38.990 INFO 6496 --- [ main] e.b.repository.DatabaseConnectionTest : Started DatabaseConnectionTest in 7.131 seconds (JVM running for 8.331) 2017-08-16 14:59:39.872 INFO 6496 --- [ main] o.n.o.drivers.http.request.HttpRequest : Thread: 1, url: http://localhost:7474/db/data/transaction/39 , request: {"statements":[{"statement":"UNWIND {rows} as row CREATE (n: User) SET n=row.props RETURN row.nodeRef as ref, ID(n) as id, row.type as type","parameters":{"rows":[{"nodeRef":-1821370276,"type":"node","props":{"password":"[email protected]","name":"Paul","email":"[email protected]","username":"paul"}}]},"resultDataContents":["row"],"includeStats":false}]} 2017-08-16 14:59:40.358 ERROR 6496 --- [ main] o.s.d.n.t.Neo4jTransactionManager : Commit exception overridden by rollback exception

org.springframework.dao.InvalidDataAccessApiUsageException: Transaction is not current for this thread; nested exception is org.neo4j.ogm.exception.TransactionManagerException: Transaction is not current for this thread

  • 为什么userRepository.save(用户)创建记录在数据库中但引发异常?
  • 什么“交易是不是当前这个线程”非常意味着什么?
  • 为什么userRepository.save(用户)最终失败,但userRepository.deleteAllUsers()的作品?

编辑:我dependencies.gradle包括以下内容:

compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-neo4j', version: '1.5.6.RELEASE' 
//compile group: 'org.springframework.data', name: 'spring-data-neo4j', version: '4.2.6.RELEASE' 
compile group: 'org.neo4j', name: 'neo4j-ogm-core', version: '2.1.3' 
//compile group: 'org.neo4j', name: 'neo4j-ogm-bolt-driver', version: '2.1.3' 
runtime group: 'org.neo4j', name: 'neo4j-ogm-http-driver', version: '2.1.3' 
compile('org.springframework.boot:spring-boot-starter-security') 
compile('org.springframework.boot:spring-boot-starter-thymeleaf') 
compile('org.springframework.boot:spring-boot-starter-web') 
compile group: 'org.springframework.boot', name: 'spring-boot-starter-actuator', version: '1.5.4.RELEASE' 
testCompile('org.springframework.boot:spring-boot-starter-test') 
+0

嗨,你能提供使用的库的版本? (春季启动,sdn,ogm ..)同时上传完整的样本将有所帮助。关键是'@ EnableTransactionManagement' - 你有,所以出于某种原因它不起作用。 –

+0

@ frant.hartm谢谢。我在上面的build.gradle中添加了依赖关系。 “完整样本”是什么意思? – PaulB

+0

一个我们可以下载并尝试的项目。 –

回答

1

SessionFactory豆不应该被声明为static

@Bean 
public static SessionFactory sessionFactory() { 
    return new SessionFactory("eu.bm.domain"); 
} 

应该

@Bean 
public SessionFactory sessionFactory() { 
    return new SessionFactory("eu.bm.domain"); 
} 

背景

“此线程的事务不是当前的”意味着某事正在尝试提交与线程本地上下文中的当前tx不同的事务。

您正在使用默认事务管理 - 它会创建一个库调用周围的事务。

当SessionFactory bean被定义为静态时,Session以某种方式看不到线程本地事务(由默认tx管理启动的事务)并创建新事务,尝试提交它并出现异常。

+0

哇...我正在看这个代码2天,现在不会注意到。非常感谢你。 – PaulB

相关问题