General Problem
I have a Node that has a Parent/Child relationship to itself (Same Label/Class). I can add a new Relathiship to a new Child node by adding the Parent Node to Parents-Relationship list (see code below). This works for saving one entity, when trying to Save the relationship for different Children of the same Parent I receive a deadlock-error (TransientDataAccessResourceException).
Setup
Maven Project
- Spring-Boot (spring-boot-starter-parent 2.6.13)
- Neo4J: spring-boot-starter-data-neo4j
- Project Lombok
- Java 11
Database: Docker-Container
docker run --name eval.neo4j -d -v eval.neo4j-data:/data -p 7474:7474 -p 7687:7687 neo4j
Config
spring:
neo4j:
uri: bolt://localhost:7687
authentication:
username: neo4j
password: admin
Java Code
Node
@Getter
@Setter
@Node("Example")
@NoArgsConstructor
public class ExampleNode {
private static final String CHILD_OF = "CHILD_OF";
@Id
@GeneratedValue
private Long id;
@Version
private Long version;
@Property
private String name;
@Relationship(type= CHILD_OF, direction = Relationship.Direction.OUTGOING)
private Set<ExampleNode> parents;
@Relationship(type= CHILD_OF, direction = Relationship.Direction.INCOMING)
private Set<ExampleNode> children;
public ExampleNode(String name) {
this.name = name;
}
public void addParent(ExampleNode parent) {
if (parents == null) {
parents = new HashSet<>();
}
parents.add(parent);
}
@Override
public String toString() {
return "ExampleNode{" +
"id=" + id +
", version=" + version +
", name='" + name + '\'' +
", parents=" + (parents == null ? 0: parents.size()) +
", children=" + (children == null ? 0 : children.size()) +
'}';
}
}
Repository:
@Transactional
public interface ExampleRepository extends CrudRepository<ExampleNode, Long> {
}
CRUD Service
@Slf4j
@Service
@RequiredArgsConstructor
public class ExampleService {
private final ExampleRepository repository;
@Transactional
public Long create(String name, Long parentId) {
ExampleNode entity = new ExampleNode(name);
if (parentId != null) {
entity.addParent(repository.findById(parentId).orElseThrow());
}
ExampleNode response = repository.save(entity);
log.info("Created {}", response);
return response.getId();
}
@Async
public Future<Long> createAsync(String name, Long parentId) {
return new AsyncResult<>(create(name, parentId));
}
public ExampleNode read(Long id) {
return repository.findById(id).orElse(null);
}
}
App with CommandLineRunner (for simplicity - the actual implementation uses RestController with spring-mvc
@Slf4j
@EnableAsync
@SpringBootApplication
public class ExampleApplication {
public static void main(String[] args) {
SpringApplication.run(ExampleApplication.class, args);
}
@Bean
CommandLineRunner runner(ExampleService service) {
return (args) -> {
Long p1 = service.create("Parent-1", null);
Long p2 = service.create("Parent-2", null);
// works for synchronous calls or when synchronizing
// before the first call. async is used to simulate
// concurrent executions i.E. via rest-calls
final Future<Long> one = service.createAsync("one", p1);
final Future<Long> two = service.createAsync("two", p1);
Long id1 = one.get(2, TimeUnit.SECONDS);
Long id2 = two.get(2, TimeUnit.SECONDS);
log.info("load parents {} {}", service.read(p1), service.read(p2));
log.info("load children {}: {}, {}:{}", id1, service.read(id1), id2, service.read(id2));
};
}
}
Log
2022-12-07 08:42:07.537 TRACE 27776 --- [ main] o.s.t.i.TransactionInterceptor : Getting transaction for [de.example.graph.service.ExampleService.create]
2022-12-07 08:42:07.550 TRACE 27776 --- [ main] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.neo4j.repository.support.SimpleNeo4jRepository.save]
2022-12-07 08:42:07.804 TRACE 27776 --- [ main] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.neo4j.repository.support.SimpleNeo4jRepository.save]
2022-12-07 08:42:07.805 INFO 27776 --- [ main] de.example.graph.service.ExampleService : Created ProblemEntity{id=35, version=0, name='Parent-1', parents=0, children=0}
2022-12-07 08:42:07.807 TRACE 27776 --- [ main] o.s.t.i.TransactionInterceptor : Completing transaction for [de.example.graph.service.ExampleService.create]
2022-12-07 08:42:07.835 TRACE 27776 --- [ main] o.s.t.i.TransactionInterceptor : Getting transaction for [de.example.graph.service.ExampleService.create]
2022-12-07 08:42:07.836 TRACE 27776 --- [ main] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.neo4j.repository.support.SimpleNeo4jRepository.save]
2022-12-07 08:42:07.854 TRACE 27776 --- [ main] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.neo4j.repository.support.SimpleNeo4jRepository.save]
2022-12-07 08:42:07.854 INFO 27776 --- [ main] de.example.graph.service.ExampleService : Created ProblemEntity{id=36, version=0, name='Parent-2', parents=0, children=0}
2022-12-07 08:42:07.854 TRACE 27776 --- [ main] o.s.t.i.TransactionInterceptor : Completing transaction for [de.example.graph.service.ExampleService.create]
2022-12-07 08:42:07.882 TRACE 27776 --- [ task-1] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.neo4j.repository.support.SimpleNeo4jRepository.findById]
2022-12-07 08:42:07.895 TRACE 27776 --- [ task-2] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.neo4j.repository.support.SimpleNeo4jRepository.findById]
2022-12-07 08:42:08.211 TRACE 27776 --- [ task-2] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.neo4j.repository.support.SimpleNeo4jRepository.findById]
2022-12-07 08:42:08.211 TRACE 27776 --- [ task-1] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.neo4j.repository.support.SimpleNeo4jRepository.findById]
2022-12-07 08:42:08.223 TRACE 27776 --- [ task-1] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.neo4j.repository.support.SimpleNeo4jRepository.save]
2022-12-07 08:42:08.223 TRACE 27776 --- [ task-2] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.neo4j.repository.support.SimpleNeo4jRepository.save]
2022-12-07 08:42:08.418 TRACE 27776 --- [ task-2] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.neo4j.repository.support.SimpleNeo4jRepository.save] after exception: org.springframework.dao.TransientDataAccessResourceException: ForsetiClient[transactionId=94, clientId=2] can't acquire ExclusiveLock{owner=ForsetiClient[transactionId=93, clientId=1]} on NODE_RELATIONSHIP_GROUP_DELETE(35), because holders of that lock are waiting for ForsetiClient[transactionId=94, clientId=2].
Wait list:ExclusiveLock[
Client[93] waits for [ForsetiClient[transactionId=94, clientId=2]]]; Error code 'Neo.TransientError.Transaction.DeadlockDetected'; nested exception is org.neo4j.driver.exceptions.TransientException: ForsetiClient[transactionId=94, clientId=2] can't acquire ExclusiveLock{owner=ForsetiClient[transactionId=93, clientId=1]} on NODE_RELATIONSHIP_GROUP_DELETE(35), because holders of that lock are waiting for ForsetiClient[transactionId=94, clientId=2].
Wait list:ExclusiveLock[
Client[93] waits for [ForsetiClient[transactionId=94, clientId=2]]]
2022-12-07 08:42:08.480 TRACE 27776 --- [ task-1] o.s.t.i.TransactionInterceptor : Completing transaction for [org.springframework.data.neo4j.repository.support.SimpleNeo4jRepository.save]
2022-12-07 08:42:08.495 INFO 27776 --- [ task-1] de.example.graph.service.ExampleService : Created ProblemEntity{id=37, version=0, name='one', parents=1, children=0}
2022-12-07 08:42:08.498 INFO 27776 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-12-07 08:42:08.537 ERROR 27776 --- [ main] o.s.boot.SpringApplication : Application run failed
java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:785) ~[spring-boot-2.6.13.jar:2.6.13]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:766) ~[spring-boot-2.6.13.jar:2.6.13]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) ~[spring-boot-2.6.13.jar:2.6.13]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1317) ~[spring-boot-2.6.13.jar:2.6.13]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[spring-boot-2.6.13.jar:2.6.13]
at de.example.graph.ExampleApplication.main(ExampleApplication.java:20) ~[classes/:na]
Caused by: java.util.concurrent.ExecutionException: org.springframework.dao.TransientDataAccessResourceException: ForsetiClient[transactionId=94, clientId=2] can't acquire ExclusiveLock{owner=ForsetiClient[transactionId=93, clientId=1]} on NODE_RELATIONSHIP_GROUP_DELETE(35), because holders of that lock are waiting for ForsetiClient[transactionId=94, clientId=2].
Wait list:ExclusiveLock[
Client[93] waits for [ForsetiClient[transactionId=94, clientId=2]]]; Error code 'Neo.TransientError.Transaction.DeadlockDetected'; nested exception is org.neo4j.driver.exceptions.TransientException: ForsetiClient[transactionId=94, clientId=2] can't acquire ExclusiveLock{owner=ForsetiClient[transactionId=93, clientId=1]} on NODE_RELATIONSHIP_GROUP_DELETE(35), because holders of that lock are waiting for ForsetiClient[transactionId=94, clientId=2].
Wait list:ExclusiveLock[
Client[93] waits for [ForsetiClient[transactionId=94, clientId=2]]]
at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122) ~[na:na]
at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:205) ~[na:na]
at de.example.graph.ExampleApplication.lambda$runner$0(ExampleApplication.java:33) ~[classes/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:782) ~[spring-boot-2.6.13.jar:2.6.13]
... 5 common frames omitted
Caused by: org.springframework.dao.TransientDataAccessResourceException: ForsetiClient[transactionId=94, clientId=2] can't acquire ExclusiveLock{owner=ForsetiClient[transactionId=93, clientId=1]} on NODE_RELATIONSHIP_GROUP_DELETE(35), because holders of that lock are waiting for ForsetiClient[transactionId=94, clientId=2].
Wait list:ExclusiveLock[
Client[93] waits for [ForsetiClient[transactionId=94, clientId=2]]]; Error code 'Neo.TransientError.Transaction.DeadlockDetected'; nested exception is org.neo4j.driver.exceptions.TransientException: ForsetiClient[transactionId=94, clientId=2] can't acquire ExclusiveLock{owner=ForsetiClient[transactionId=93, clientId=1]} on NODE_RELATIONSHIP_GROUP_DELETE(35), because holders of that lock are waiting for ForsetiClient[transactionId=94, clientId=2].
Wait list:ExclusiveLock[
Client[93] waits for [ForsetiClient[transactionId=94, clientId=2]]]
at org.springframework.data.neo4j.core.Neo4jPersistenceExceptionTranslator.translateImpl(Neo4jPersistenceExceptionTranslator.java:107) ~[spring-data-neo4j-6.2.9.jar:6.2.9]
at org.springframework.data.neo4j.core.Neo4jPersistenceExceptionTranslator.translateExceptionIfPossible(Neo4jPersistenceExceptionTranslator.java:79) ~[spring-data-neo4j-6.2.9.jar:6.2.9]
at org.springframework.data.neo4j.core.DefaultNeo4jClient.potentiallyConvertRuntimeException(DefaultNeo4jClient.java:233) ~[spring-data-neo4j-6.2.9.jar:6.2.9]
at org.springframework.data.neo4j.core.DefaultNeo4jClient.access$600(DefaultNeo4jClient.java:62) ~[spring-data-neo4j-6.2.9.jar:6.2.9]
at org.springframework.data.neo4j.core.DefaultNeo4jClient$DefaultRecordFetchSpec.one(DefaultNeo4jClient.java:461) ~[spring-data-neo4j-6.2.9.jar:6.2.9]
at org.springframework.data.neo4j.core.Neo4jTemplate.lambda$processNestedRelations$25(Neo4jTemplate.java:865) ~[spring-data-neo4j-6.2.9.jar:6.2.9]
at org.springframework.data.mapping.model.BasicPersistentEntity.doWithAssociations(BasicPersistentEntity.java:388) ~[spring-dat开发者_Python百科a-commons-2.6.9.jar:2.6.9]
at org.springframework.data.neo4j.core.Neo4jTemplate.processNestedRelations(Neo4jTemplate.java:729) ~[spring-data-neo4j-6.2.9.jar:6.2.9]
at org.springframework.data.neo4j.core.Neo4jTemplate.processRelations(Neo4jTemplate.java:714) ~[spring-data-neo4j-6.2.9.jar:6.2.9]
at org.springframework.data.neo4j.core.Neo4jTemplate.saveImpl(Neo4jTemplate.java:433) ~[spring-data-neo4j-6.2.9.jar:6.2.9]
at org.springframework.data.neo4j.core.Neo4jTemplate.save(Neo4jTemplate.java:345) ~[spring-data-neo4j-6.2.9.jar:6.2.9]
at org.springframework.data.neo4j.repository.support.SimpleNeo4jRepository.save(SimpleNeo4jRepository.java:119) ~[spring-data-neo4j-6.2.9.jar:6.2.9]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:289) ~[spring-data-commons-2.6.9.jar:2.6.9]
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137) ~[spring-data-commons-2.6.9.jar:2.6.9]
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121) ~[spring-data-commons-2.6.9.jar:2.6.9]
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:530) ~[spring-data-commons-2.6.9.jar:2.6.9]
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:286) ~[spring-data-commons-2.6.9.jar:2.6.9]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:640) ~[spring-data-commons-2.6.9.jar:2.6.9]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:164) ~[spring-data-commons-2.6.9.jar:2.6.9]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:139) ~[spring-data-commons-2.6.9.jar:2.6.9]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.23.jar:5.3.23]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.23.jar:5.3.23]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.23.jar:5.3.23]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) ~[spring-tx-5.3.23.jar:5.3.23]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.23.jar:5.3.23]
at com.sun.proxy.$Proxy64.save(Unknown Source) ~[na:na]
at de.example.graph.service.ExampleService.create(ExampleService.java:27) ~[classes/:na]
at de.example.graph.service.ExampleService.createAsync(ExampleService.java:34) ~[classes/:na]
at de.example.graph.service.ExampleService$$FastClassBySpringCGLIB$$91503e55.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.23.jar:5.3.23]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115) ~[spring-aop-5.3.23.jar:5.3.23]
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
at java.base/java.lang.Thread.run(Thread.java:839) ~[na:na]
Caused by: org.neo4j.driver.exceptions.TransientException: ForsetiClient[transactionId=94, clientId=2] can't acquire ExclusiveLock{owner=ForsetiClient[transactionId=93, clientId=1]} on NODE_RELATIONSHIP_GROUP_DELETE(35), because holders of that lock are waiting for ForsetiClient[transactionId=94, clientId=2].
Wait list:ExclusiveLock[
Client[93] waits for [ForsetiClient[transactionId=94, clientId=2]]]
at org.neo4j.driver.internal.util.Futures.blockingGet(Futures.java:111) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.InternalResult.blockingGet(InternalResult.java:107) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.InternalResult.hasNext(InternalResult.java:53) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.springframework.data.neo4j.core.DefaultNeo4jClient$DefaultRecordFetchSpec.one(DefaultNeo4jClient.java:455) ~[spring-data-neo4j-6.2.9.jar:6.2.9]
... 43 common frames omitted
Suppressed: org.neo4j.driver.internal.util.ErrorUtil$InternalExceptionCause: null
at org.neo4j.driver.internal.util.ErrorUtil.newNeo4jError(ErrorUtil.java:80) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher.handleFailureMessage(InboundMessageDispatcher.java:107) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.messaging.common.CommonMessageReader.unpackFailureMessage(CommonMessageReader.java:75) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.messaging.common.CommonMessageReader.read(CommonMessageReader.java:53) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.async.inbound.InboundMessageHandler.channelRead0(InboundMessageHandler.java:81) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.async.inbound.InboundMessageHandler.channelRead0(InboundMessageHandler.java:37) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:327) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:299) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.async.inbound.MessageDecoder.channelRead(MessageDecoder.java:42) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:327) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:299) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:722) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:658) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:584) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:496) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
at org.neo4j.driver.internal.shaded.io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[neo4j-java-driver-4.4.9.jar:4.4.9-e855bcc800deff6ddcf064c822314bb5c8d08c53]
... 1 common frames omitted
2022-12-07 08:42:08.543 INFO 27776 --- [ main] o.neo4j.driver.internal.InternalDriver : Closing driver instance -634758184
2022-12-07 08:42:08.548 INFO 27776 --- [ main] o.n.d.i.async.pool.ConnectionPoolImpl : Closing connection pool towards localhost:7687
Process finished with exit code 1
Problem
Saving the second Child node seems to be locked by the first (or the other way around). I thought this would be resolved by the transaction annotation. I am also worried about NODE_RELATIONSHIP_GROUP_DELETE
in the log-output - this seems to indicate that the first child will be removed when saving the second.
I was unable to find a simple spring-like solution for only saving the node and the relationship without touching the parent-node, since the parent node properties are unchanged.
Thank you for your Help :)
精彩评论