我有一个Spring引导应用程序,它在字段上有一个具有唯一性约束的实体。
我运行弹簧-引导,弹簧-数据-新4j,新4j-奥GM,螺栓驱动器和neo4j 3.2码头形象。
当我运行IT测试时,我首先保存一些数据,然后尝试持久化相同的数据以获得要触发的约束。
唯一性约束按预期的方式进入,并抛出一个ClientException。这将被捕获,并将适当的异常返回给客户端。
然后,在下面的测试中,我只是尝试保存一些数据,当服务器在GraphRepository中运行save()时突然冻结。
因此,我的问题是,为什么在我的情况下,由于唯一性约束而抛出了一个之后,neo4j在所有的事务中都会完全冻结。日志什么也没说,neo4j debug.log什么也没说。
如果我把每个测试分开运行,它们都会通过。运行在一起,它冻结测试后,在测试的neo4j。
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<groupId>se.andolf</groupId>
<artifactId>lift</artifactId>
<version>0.0.1-SNAPSHOT</version>
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<modules>
<module>lift-api</module>
<module>lift-service</module>
<module>lift-app</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring.boot.version>1.5.3.RELEASE</spring.boot.version>
<spring-data-releasetrain.version>Ingalls-SR3</spring-data-releasetrain.version>
<neo4j-ogm.version>2.1.2</neo4j-ogm.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-releasetrain</artifactId>
<version>Ingalls-SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>se.andolf</groupId>
<artifactId>lift-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>se.andolf</groupId>
<artifactId>lift-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>se.andolf</groupId>
<artifactId>lift-service</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-core</artifactId>
<version>${neo4j-ogm.version}</version>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-bolt-driver</artifactId>
<version>${neo4j-ogm.version}</version>
</dependency>
<dependency>
<groupId>com.github.jmnarloch</groupId>
<artifactId>modelmapper-spring-boot-starter</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.uuid</groupId>
<artifactId>java-uuid-generator</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>com.github.fge</groupId>
<artifactId>json-patch</artifactId>
<version>1.9</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring.boot.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>3.0.3</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.18.1</version>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.11</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>integration-tests</id>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.7.201606060606</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>default-prepare-agent-integration</id>
<goals>
<goal>prepare-agent-integration</goal>
</goals>
</execution>
<execution>
<id>default-report</id>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>default-report-integration</id>
<goals>
<goal>report-integration</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>coveralls</id>
<build>
<plugins>
<plugin>
<groupId>org.eluder.coveralls</groupId>
<artifactId>coveralls-maven-plugin</artifactId>
<version>4.3.0</version>
</plugin>
</plugins>
</build>
</profile>
</profiles>
lift-service/头.lift
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>lift</artifactId>
<groupId>se.andolf</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>lift-service</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>se.andolf</groupId>
<artifactId>lift-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-core</artifactId>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-bolt-driver</artifactId>
</dependency>
<dependency>
<groupId>com.github.fge</groupId>
<artifactId>json-patch</artifactId>
</dependency>
<dependency>
<groupId>com.github.jmnarloch</groupId>
<artifactId>modelmapper-spring-boot-starter</artifactId>
</dependency>
</dependencies>
会话bean配置:
@Configuration
@EnableNeo4jRepositories(basePackages = "se.andolf")
@EnableTransactionManagement
public class SessionConfig {
@Bean
public SessionFactory sessionFactory(){
LOG.debug("Loading session factory");
return new SessionFactory("se.andolf");
}
@Bean
public Neo4jTransactionManager transactionManager() {
return new Neo4jTransactionManager(sessionFactory());
}
}CategoryController.class
@RestController
@Api(tags = { "Categories" })
public class CategoryController {
@Autowired
private CategoryService categoryService;
@RequestMapping(method=PUT, value="/categories")
@ResponseStatus(HttpStatus.CREATED)
public ResponseEntity<Void> add(
@RequestBody Category category, HttpServletRequest request) throws URISyntaxException {
final Long id = categoryService.save(category);
final HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setLocation(new URI(request.getRequestURL().toString() + "/" + id));
return new ResponseEntity<>(responseHeaders, HttpStatus.CREATED);
}
}CategoryService.class
@Service
@Transactional
public class CategoryService {
private static Log LOG = LogFactory.getLog(CategoryService.class);
@Autowired
private CategoryRepository categoryRepository;
public Long save(Category category){
final CategoryEntity categoryEntity = new CategoryEntity(category.getName());
try {
return categoryRepository.save(categoryEntity).getId();
} catch (ClientException e) {
LOG.error("Category " + category.getName() + " exists select another name", e);
throw new NodeExistsException("Category " + category.getName() + " exists please select another name");
}
}
}CategoryEntity.class
@NodeEntity
public class CategoryEntity {
@GraphId
private Long id;
@Index(unique=true)
private String name;
public CategoryEntity() {
}
public CategoryEntity(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}ogm.properties
driver=org.neo4j.ogm.drivers.bolt.driver.BoltDriver
URI=bolt://neo4j:password@localhost
connection.pool.size=150
indexes.auto=asserttravic-ci日志中的最后一行
2017-05-28 08:58:34.316 DEBUG 7082 --- [nio-8080-exec-4] o.n.ogm.drivers.bolt.driver.BoltDriver : No current transaction, starting a new one
2017-05-28 08:58:34.317 DEBUG 7082 --- [nio-8080-exec-4] o.n.ogm.drivers.bolt.driver.BoltDriver : Native transaction: org.neo4j.driver.internal.ExplicitTransaction@7e0a0bb1
2017-05-28 08:58:34.317 DEBUG 7082 --- [nio-8080-exec-4] org.neo4j.ogm.session.Neo4jSession : Thread 20: Transaction, tx id: org.neo4j.ogm.drivers.bolt.transaction.BoltTransaction@53533858
2017-05-28 08:58:34.318 DEBUG 7082 --- [nio-8080-exec-4] o.s.d.n.t.Neo4jTransactionManager : Beginning Transaction [org.neo4j.ogm.drivers.bolt.transaction.BoltTransaction@53533858] on Session [org.neo4j.ogm.session.Neo4jSession@730479f]
2017-05-28 08:58:34.318 DEBUG 7082 --- [nio-8080-exec-4] o.s.d.n.t.Neo4jTransactionManager : Found thread-bound Session [org.neo4j.ogm.session.Neo4jSession@730479f] for Neo4j OGM transaction
2017-05-28 08:58:34.318 DEBUG 7082 --- [nio-8080-exec-4] o.s.d.n.t.Neo4jTransactionManager : Participating in existing transaction
2017-05-28 08:58:34.319 DEBUG 7082 --- [nio-8080-exec-4] org.neo4j.ogm.context.EntityGraphMapper : context initialised with 0 relationships
2017-05-28 08:58:34.319 DEBUG 7082 --- [nio-8080-exec-4] org.neo4j.ogm.context.EntityGraphMapper : visiting: se.andolf.entities.CategoryEntity@7a132ac9
2017-05-28 08:58:34.319 DEBUG 7082 --- [nio-8080-exec-4] org.neo4j.ogm.context.EntityGraphMapper : se.andolf.entities.CategoryEntity@7a132ac9 has changed
2017-05-28 08:58:34.319 DEBUG 7082 --- [nio-8080-exec-4] org.neo4j.ogm.context.EntityGraphMapper : mapping references declared by: se.andolf.entities.CategoryEntity@7a132ac9
2017-05-28 08:58:34.320 INFO 7082 --- [nio-8080-exec-4] o.n.o.drivers.bolt.request.BoltRequest : Request: UNWIND {rows} as row CREATE (n:`CategoryEntity`) SET n=row.props RETURN row.nodeRef as ref, ID(n) as id, row.type as type with params {rows=[{nodeRef=-2048076489, type=node, props={name=Arms}}]}
No output has been received in the last 10m0s, this potentially indicates a stalled build or something wrong with the build itself.
Check the details on how to adjust your build configuration on: https://docs.travis-ci.com/user/common-build-problems/#Build-times-out-because-no-output-was-received
The build has been terminated在这里可以找到完整的日志:Travis-ci构建日志
CategoriesControllerIT.class
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = DEFINED_PORT)
public class CategoriesControllerIT {
@Test
public void shouldReturn409ConflictIfCategoryNameExists(){
final Category category = new Category("Arms");
final String id = put(category);
given()
.contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
.body(category)
.when()
.put("/categories")
.then()
.statusCode(HttpStatus.CONFLICT.value());
deleteCategory(id);
}
@Test
public void shouldSaveCategory(){
final Category category = new Category("Arms");
final String header = given()
.contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
.body(category)
.when()
.put("/categories")
.then()
.assertThat()
.statusCode(201)
.header("Location", is(notNullValue()))
.extract().response().getHeader("Location");
deleteCategory(UriUtil.extractLastPath(header));
}
private String put(Category category) {
try {
final String header = given().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE).body(category).put("/categories").getHeader("Location");
return UriUtil.extractLastPath(header);
} catch (Exception e) {
throw new AssertionError(e);
}
}
}命令将neo4j作为IT测试的对接程序运行。
docker run -d --name neo4j --publish=7474:7474 --publish=7687:7687 --env=NEO4J_AUTH=neo4j/password neo4j:3.2这只是完整代码基的摘录,我已经粘贴了我认为相关的内容。完整的代码可以在这里找到:
发布于 2017-05-30 17:13:35
在获得有关新4j用户松懈的帮助之后,问题是在事务关闭时,驱动程序在关闭会话时遇到了问题。
这个问题在新4j-ogm的2.1.3版本的螺栓驱动程序中得到了修正。
因此,从2.1.2 -> 2.1.3中选择ogm版本解决了这个问题。
相关问题:当事务关闭时,使回滚关闭螺栓会话
java-驱动程序的相关问题:java-驱动程序版本1.3.1
https://stackoverflow.com/questions/44262725
复制相似问题