Spring Data Neo4j InvalidDataAccessApiUsageException:事务不是该线程的当前事务
Spring Data Neo4j InvalidDataAccessApiUsageException: Transaction is not current for this thread
我有一个 Spring 启动 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 : 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":"p@ss","name":"Paul","email":"paul@user.com","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(user)在数据库中创建记录却抛出异常?
- "Transaction is not current for this thread" 究竟是什么意思?
- 为什么 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')
您的 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 管理启动的事务)中的事务并创建新事务,尝试提交它并出现异常。
我有一个 Spring 启动 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 : 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":"p@ss","name":"Paul","email":"paul@user.com","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 exceptionorg.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(user)在数据库中创建记录却抛出异常?
- "Transaction is not current for this thread" 究竟是什么意思?
- 为什么 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')
您的 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 管理启动的事务)中的事务并创建新事务,尝试提交它并出现异常。