【问题标题】:Spring Data Neo4j InvalidDataAccessApiUsageException: Transaction is not current for this threadSpring Data Neo4j InvalidDataAccessApiUsageException:该线程的事务不是当前的
【发布时间】:2017-08-16 14:37:28
【问题描述】:

我有一个 Spring boot neo4j 应用程序,想将用户存储在 Neo4j 数据库中。我按照here 的说明进行操作。 neo4j的配置是这样的:

@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 = "paul@user.com";
private static final String PASSWORD1 = "p@ss";
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:在 7.131 秒内启动 DatabaseConnectionTest(JVM 运行 8.331) 2017-08-16 14:59:39.872 INFO 6496 --- [main] o.n.o.drivers.http.request.HttpRequest:线程:1,url:http://localhost:7474/db/data/transaction/39,请求:{“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":"p@ss","name":"Paul","email":"paul@user. com","username":"paul"}}]},"resultDataContents":["row"],"includeStats":false}]} 2017-08-16 14:59:40.358 错误 6496 --- [main] o.s.d.n.t.Neo4jTransactionManager:提交异常被回滚异常覆盖

org.springframework.dao.InvalidDataAccessApiUsageException:该线程的事务不是当前的;嵌套异常是 org.neo4j.ogm.exception.TransactionManagerException: Transaction is not current for this thread

  • 为什么userRepository.save(user)在数据库中创建记录却抛出异常?
  • “此线程的事务不是当前的”究竟是什么意思?
  • 为什么 userRepository.save(user) 最终会失败,但 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')

【问题讨论】:

  • 您好,您能提供使用的库的版本吗? (spring boot,sdn,ogm ..)上传完整样本也会有所帮助。关键是 @EnableTransactionManagement - 你有它,所以由于某种原因它不起作用。
  • @frant.hartm 谢谢。我添加了上面 build.gradle 中使用的依赖项。 “完整样本”是什么意思?
  • 一个可以下载试用的项目。
  • @frant.hartm 我在这里添加了它:gitlab.com/pbount/bm

标签: spring spring-boot neo4j spring-data-neo4j-4 neo4j-ogm


【解决方案1】:

您的 SessionFactory bean 不应声明为 static:

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

应该是

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

背景

"Transaction is not current for this thread" 意味着有东西试图提交一个与线程本地上下文中的当前 tx 不同的事务。

您正在使用默认事务管理 - 它围绕存储库调用创建事务。

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

【讨论】:

  • 哇...我已经查看了 2 天的代码,但从未注意到。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2015-05-04
  • 2018-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多