Skip to content

Ids need to be potentially converted before dynamic labels are determined. #2296

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
thiagohmoreira opened this issue Jun 21, 2021 · 1 comment
Assignees
Labels
type: bug A general bug

Comments

@thiagohmoreira
Copy link

Issue

Cannot save node entities that have UUID field as @Id and other field with @DynamicLabels. For instance:

@Node
public class Entity {
    @Id
    @GeneratedValue
    private UUID id;

    @DynamicLabels
    private Set<String> extraLabels;
...
}

Environment

  • Spring Boot 2.5.1 (also tested with 2.5.0)
  • Spring Data Neo4j 6.1.1
  • Neo4j Community 4.3.0 (also tested on 4.1.1)
  • JDK 11.0.5 (also tested on JDK 8)

Example project

This is a super simple example application, that will try to clean up the repository and create a node afterwards: neo4j_test.zip

Exception

The relevant log portion (with DEBUG enabled for org.springframework.data.neo4j):

DEBUG 8608 --- [           main] o.s.d.n.c.t.Neo4jTransactionManager      : Creating new transaction with name [org.springframework.data.neo4j.repository.support.SimpleNeo4jRepository.save]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
DEBUG 8608 --- [           main] org.springframework.data.neo4j.cypher    : Executing:
MATCH (n) WHERE n.id = $__id__ UNWIND labels(n) AS label WITH label WHERE NOT (label IN $__staticLabels__) RETURN collect(label) AS __nodeLabels__
WARN 8608 --- [           main] .n.c.Neo4jPersistenceExceptionTranslator : Don't know how to translate exception of type class java.lang.reflect.UndeclaredThrowableException
...
Caused by: java.lang.reflect.UndeclaredThrowableException: null
	at org.springframework.data.neo4j.core.$Proxy69.run(Unknown Source) ~[na:6.1.1]
	at org.springframework.data.neo4j.core.DefaultNeo4jClient$RunnableStatement.runWith(DefaultNeo4jClient.java:167) ~[spring-data-neo4j-6.1.1.jar:6.1.1]
	at org.springframework.data.neo4j.core.DefaultNeo4jClient$DefaultRecordFetchSpec.one(DefaultNeo4jClient.java:304) ~[spring-data-neo4j-6.1.1.jar:6.1.1]
	at org.springframework.data.neo4j.core.Neo4jTemplate.lambda$determineDynamicLabels$6(Neo4jTemplate.java:378) ~[spring-data-neo4j-6.1.1.jar:6.1.1]
	at java.base/java.util.Optional.map(Optional.java:265) ~[na:na]
	at org.springframework.data.neo4j.core.Neo4jTemplate.determineDynamicLabels(Neo4jTemplate.java:363) ~[spring-data-neo4j-6.1.1.jar:6.1.1]
	at org.springframework.data.neo4j.core.Neo4jTemplate.saveImpl(Neo4jTemplate.java:324) ~[spring-data-neo4j-6.1.1.jar:6.1.1]
	at org.springframework.data.neo4j.core.Neo4jTemplate.save(Neo4jTemplate.java:288) ~[spring-data-neo4j-6.1.1.jar:6.1.1]
	at org.springframework.data.neo4j.repository.support.SimpleNeo4jRepository.save(SimpleNeo4jRepository.java:117) ~[spring-data-neo4j-6.1.1.jar:6.1.1]
	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.5.1.jar:2.5.1]
	at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:529) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:599) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.8.jar:5.3.8]
	at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:163) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:138) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.8.jar:5.3.8]
	at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.8.jar:5.3.8]
	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.8.jar:5.3.8]
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.8.jar:5.3.8]
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.8.jar:5.3.8]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.8.jar:5.3.8]
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) ~[spring-tx-5.3.8.jar:5.3.8]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.8.jar:5.3.8]
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-5.3.8.jar:5.3.8]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.8.jar:5.3.8]
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.8.jar:5.3.8]
	at com.sun.proxy.$Proxy54.save(Unknown Source) ~[na:na]
	at com.example.neo4j_test.Neo4jTestApplication.lambda$demo$0(Neo4jTestApplication.java:25) ~[main/:na]
	at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:791) ~[spring-boot-2.5.1.jar:2.5.1]
	... 5 common frames omitted
Caused by: java.lang.reflect.InvocationTargetException: null
	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.neo4j.core.DefaultNeo4jClient$AutoCloseableQueryRunnerHandler.invoke(DefaultNeo4jClient.java:110) ~[spring-data-neo4j-6.1.1.jar:6.1.1]
	... 42 common frames omitted
Caused by: org.neo4j.driver.exceptions.ClientException: Unable to convert java.util.UUID to Neo4j Value.
	at org.neo4j.driver.Values.value(Values.java:134) ~[neo4j-java-driver-4.2.6.jar:4.2.6-d30b7a1cc46cfbe9dffc9a684960ee30799302a0]
	at org.neo4j.driver.internal.util.Extract.mapOfValues(Extract.java:203) ~[neo4j-java-driver-4.2.6.jar:4.2.6-d30b7a1cc46cfbe9dffc9a684960ee30799302a0]
	at org.neo4j.driver.internal.AbstractQueryRunner.parameters(AbstractQueryRunner.java:69) ~[neo4j-java-driver-4.2.6.jar:4.2.6-d30b7a1cc46cfbe9dffc9a684960ee30799302a0]
	at org.neo4j.driver.internal.AbstractQueryRunner.run(AbstractQueryRunner.java:43) ~[neo4j-java-driver-4.2.6.jar:4.2.6-d30b7a1cc46cfbe9dffc9a684960ee30799302a0]
	... 47 common frames omitted

Other information

The issue don't happen if any of the conditions bellow are true:

  • @Id field is another datatype (like Long);
  • Entity don't have a field annotated with @DynamicLabels.
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jun 21, 2021
@michael-simons michael-simons self-assigned this Jun 21, 2021
@michael-simons
Copy link
Collaborator

Thanks @thiagohmoreira I can reproduce this and it will be fixed in the next patch.

@michael-simons michael-simons added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged labels Jun 21, 2021
@michael-simons michael-simons changed the title "Unable to convert java.util.UUID to Neo4j Value" when using @DynamicLabels Ids need to be potentially converted before dynamic labels are determined. Jun 21, 2021
@michael-simons michael-simons added this to the 6.0.10 (2020.0.10) milestone Jun 21, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

No branches or pull requests

3 participants