Spring (Boot, Data Neo4j), Neo4j: cannot create @QueryResult with a Kotlin class





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







0















I'm struggling to create a projection of a node entity Event with a Kotlin class using Spring Data Neo4j's @QueryResult and a custom @Query.



NodeEntity: Event.java



@NodeEntity
// getter, setter, ... boilerplate (lombok)
@Data @NoArgsConstructor @AllArgsConstructor
class Event {
@Id
@GeneratedValue
private Long id;
private LocalDateTime timestamp;
private String name;
}


Repo: EventRepo.java



@Repository
interface EventRepo extends Neo4jRepository<Event, Long> {
// works
@Query("MATCH (e:Event) " +
"RETURN id(e) AS id, e.timestamp AS timestamp, e.name AS name")
EventDtoJava findAsJavaDto();

// meh
@Query("MATCH (e:Event) " +
"RETURN id(e) AS id, e.timestamp AS timestamp, e.name AS name")
EventDtoKotlin findAsKotlinDto();
}


Projections: Java and Kotlin version



// Projection with a Java class: works
@QueryResult
// getter, setter, ... boilerplate (lombok)
@Data
class EventDtoJava {
private Long id;
private LocalDateTime timestamp;
private String name;
}


// Projection with a Kotlin class: meh
@QueryResult
data class EventDtoKotlin(
var id: Long,
var timestamp: LocalDateTime,
var name: String
)


The exactly same query that worked for EventDtoJava (EventRepo.findAsJavaDto()) fails with the Kotlin class (EventRepo.findAsKotlinDto()).



As a workaround I could use Java DTOs but this doesn't solve the underlying issue.



As suggested in https://stackoverflow.com/a/52475719 I already added java.time support to Neo4j's ObjectMapper.



I suspected that com.fasterxml.jackson.module:jackson-module-kotlin was missing from their ObjectMapper, but this changed nothing.



Edit: The exception can also be triggered by creating an all args constructor in EventDtoJava.



MATCH (e:Event) RETURN id(e) AS id, e.timestamp AS timestamp, e.name AS name



Exception in thread "main" org.springframework.data.mapping.model.MappingInstantiationException: Failed to instantiate com.example.demo.EventDtoKotlin using constructor fun <init>(kotlin.Long, java.time.LocalDateTime, kotlin.String): com.example.demo.EventDtoKotlin with arguments 0,2019-01-03T15:11:04.581095,test!
at org.springframework.data.convert.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(ClassGeneratingEntityInstantiator.java:228)
at org.springframework.data.convert.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:84)
at org.springframework.data.neo4j.conversion.Neo4jOgmEntityInstantiatorAdapter.createInstance(Neo4jOgmEntityInstantiatorAdapter.java:58)
at org.springframework.data.neo4j.repository.query.QueryResultInstantiator.createInstance(QueryResultInstantiator.java:52)
at org.neo4j.ogm.metadata.reflect.EntityFactory.instantiate(EntityFactory.java:121)
at org.neo4j.ogm.metadata.reflect.EntityFactory.newObject(EntityFactory.java:90)
at org.neo4j.ogm.context.SingleUseEntityMapper.map(SingleUseEntityMapper.java:91)
at org.springframework.data.neo4j.repository.query.CustomResultConverter.convert(CustomResultConverter.java:80)
at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:224)
at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.lambda$and$0(ResultProcessor.java:210)
at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:224)
at org.springframework.data.repository.query.ResultProcessor.processResult(ResultProcessor.java:166)
at org.springframework.data.neo4j.repository.query.GraphRepositoryQuery.doExecute(GraphRepositoryQuery.java:72)
at org.springframework.data.neo4j.repository.query.AbstractGraphRepositoryQuery.execute(AbstractGraphRepositoryQuery.java:52)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:605)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$invoke$3(RepositoryFactorySupport.java:595)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:595)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.example.demo.$Proxy97.findAsKotlinDto(Unknown Source)
at com.example.demo.DemoApplication.main(DemoApplication.java:24)
Caused by: java.lang.ClassCastException: class java.lang.String cannot be cast to class java.time.LocalDateTime (java.lang.String and java.time.LocalDateTime are in module java.base of loader 'bootstrap')
at com.example.demo.EventDtoKotlin_Instantiator_5tss1f.newInstance(Unknown Source)
at org.springframework.data.convert.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(ClassGeneratingEntityInstantiator.java:226)
... 31 more


I tried to wrap e.timestamp in localdatetime() without success:



MATCH (e:Event) RETURN id(e) AS id, localdatetime(e.timestamp) AS timestamp, e.name AS name



// with MATCH (e:Event) RETURN id(e) AS id, localdatetime(e.timestamp) AS timestamp, e.name AS name

Exception in thread "main" java.lang.ClassCastException: class java.time.LocalDateTime cannot be cast to class java.lang.String (java.time.LocalDateTime and java.lang.String are in module java.base of loader 'bootstrap')
at org.neo4j.ogm.typeconversion.LocalDateTimeStringConverter.toEntityAttribute(LocalDateTimeStringConverter.java:25)
at org.neo4j.ogm.metadata.FieldInfo.write(FieldInfo.java:368)
at org.neo4j.ogm.context.SingleUseEntityMapper.writeProperty(SingleUseEntityMapper.java:143)
at org.neo4j.ogm.context.SingleUseEntityMapper.setPropertiesOnEntity(SingleUseEntityMapper.java:99)
at org.neo4j.ogm.context.SingleUseEntityMapper.map(SingleUseEntityMapper.java:92)
at org.springframework.data.neo4j.repository.query.CustomResultConverter.convert(CustomResultConverter.java:80)
at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:224)
at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.lambda$and$0(ResultProcessor.java:210)
at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:224)
at org.springframework.data.repository.query.ResultProcessor.processResult(ResultProcessor.java:166)
at org.springframework.data.neo4j.repository.query.GraphRepositoryQuery.doExecute(GraphRepositoryQuery.java:72)
at org.springframework.data.neo4j.repository.query.AbstractGraphRepositoryQuery.execute(AbstractGraphRepositoryQuery.java:52)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:605)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$invoke$3(RepositoryFactorySupport.java:595)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:595)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.example.demo.$Proxy97.findAsJavaDto(Unknown Source)
at com.example.demo.DemoApplication.main(DemoApplication.java:23)


Repro



Create a Spring Initializer project with Gradle and replace the build.gradle with the following content:



build.gradle



plugins {
id "org.jetbrains.kotlin.jvm" version "1.3.11"

id("io.spring.dependency-management") version "1.0.6.RELEASE"
id("org.springframework.boot") version "2.1.1.RELEASE"
id("org.jetbrains.kotlin.plugin.spring") version "1.3.11"
id("org.jetbrains.kotlin.plugin.noarg") version "1.3.11"
}

repositories {
jcenter()
}
sourceCompatibility = 11
targetCompatibility = 11

ext['jackson.version'] = '2.9.8'

noArg {
annotation("org.neo4j.ogm.annotation.NodeEntity")
annotation("org.neo4j.ogm.annotation.RelationshipEntity")
annotation("org.springframework.data.neo4j.annotation.QueryResult")
}

compileKotlin {
kotlinOptions {
jvmTarget = 1.8
javaParameters = true
}
}


dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation('org.springframework.boot:spring-boot-starter-json')
// jackson kotlin classes support
implementation('com.fasterxml.jackson.module:jackson-module-kotlin')

implementation('org.springframework.boot:spring-boot-starter-data-neo4j')
runtimeOnly('org.neo4j:neo4j:3.5.1')
runtimeOnly('org.neo4j:neo4j-ogm-embedded-driver:3.1.5')

compileOnly('org.projectlombok:lombok')
annotationProcessor('org.projectlombok:lombok')
}


DemoApplication.java



package com.example.demo;

import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.module.kotlin.KotlinModule;
import lombok.val;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.time.LocalDateTime;
import java.util.Objects;

@SpringBootApplication
public class DemoApplication {
public static void main(String args) {
var ctx = SpringApplication.run(DemoApplication.class, args);
setupNeo4jJavaTimeSupport();
var repo = ctx.getBean(EventRepo.class);

var e = repo.save(new Event(null, LocalDateTime.now(), "test!"));
System.out.println();
System.out.println("e = " + e);
System.out.println("java: " + Objects.requireNonNull(repo.findAsJavaDto()));
System.out.println("kotlin" + Objects.requireNonNull(repo.findAsKotlinDto()));
}

private static void setupNeo4jJavaTimeSupport() {
// see https://stackoverflow.com/a/52475719
var ogmObjectMapper = org.neo4j.ogm.config.ObjectMapperFactory.objectMapper();
ogmObjectMapper.registerModule(new JavaTimeModule());
ogmObjectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

ogmObjectMapper.registerModule(new KotlinModule());
}
}









share|improve this question































    0















    I'm struggling to create a projection of a node entity Event with a Kotlin class using Spring Data Neo4j's @QueryResult and a custom @Query.



    NodeEntity: Event.java



    @NodeEntity
    // getter, setter, ... boilerplate (lombok)
    @Data @NoArgsConstructor @AllArgsConstructor
    class Event {
    @Id
    @GeneratedValue
    private Long id;
    private LocalDateTime timestamp;
    private String name;
    }


    Repo: EventRepo.java



    @Repository
    interface EventRepo extends Neo4jRepository<Event, Long> {
    // works
    @Query("MATCH (e:Event) " +
    "RETURN id(e) AS id, e.timestamp AS timestamp, e.name AS name")
    EventDtoJava findAsJavaDto();

    // meh
    @Query("MATCH (e:Event) " +
    "RETURN id(e) AS id, e.timestamp AS timestamp, e.name AS name")
    EventDtoKotlin findAsKotlinDto();
    }


    Projections: Java and Kotlin version



    // Projection with a Java class: works
    @QueryResult
    // getter, setter, ... boilerplate (lombok)
    @Data
    class EventDtoJava {
    private Long id;
    private LocalDateTime timestamp;
    private String name;
    }


    // Projection with a Kotlin class: meh
    @QueryResult
    data class EventDtoKotlin(
    var id: Long,
    var timestamp: LocalDateTime,
    var name: String
    )


    The exactly same query that worked for EventDtoJava (EventRepo.findAsJavaDto()) fails with the Kotlin class (EventRepo.findAsKotlinDto()).



    As a workaround I could use Java DTOs but this doesn't solve the underlying issue.



    As suggested in https://stackoverflow.com/a/52475719 I already added java.time support to Neo4j's ObjectMapper.



    I suspected that com.fasterxml.jackson.module:jackson-module-kotlin was missing from their ObjectMapper, but this changed nothing.



    Edit: The exception can also be triggered by creating an all args constructor in EventDtoJava.



    MATCH (e:Event) RETURN id(e) AS id, e.timestamp AS timestamp, e.name AS name



    Exception in thread "main" org.springframework.data.mapping.model.MappingInstantiationException: Failed to instantiate com.example.demo.EventDtoKotlin using constructor fun <init>(kotlin.Long, java.time.LocalDateTime, kotlin.String): com.example.demo.EventDtoKotlin with arguments 0,2019-01-03T15:11:04.581095,test!
    at org.springframework.data.convert.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(ClassGeneratingEntityInstantiator.java:228)
    at org.springframework.data.convert.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:84)
    at org.springframework.data.neo4j.conversion.Neo4jOgmEntityInstantiatorAdapter.createInstance(Neo4jOgmEntityInstantiatorAdapter.java:58)
    at org.springframework.data.neo4j.repository.query.QueryResultInstantiator.createInstance(QueryResultInstantiator.java:52)
    at org.neo4j.ogm.metadata.reflect.EntityFactory.instantiate(EntityFactory.java:121)
    at org.neo4j.ogm.metadata.reflect.EntityFactory.newObject(EntityFactory.java:90)
    at org.neo4j.ogm.context.SingleUseEntityMapper.map(SingleUseEntityMapper.java:91)
    at org.springframework.data.neo4j.repository.query.CustomResultConverter.convert(CustomResultConverter.java:80)
    at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:224)
    at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.lambda$and$0(ResultProcessor.java:210)
    at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:224)
    at org.springframework.data.repository.query.ResultProcessor.processResult(ResultProcessor.java:166)
    at org.springframework.data.neo4j.repository.query.GraphRepositoryQuery.doExecute(GraphRepositoryQuery.java:72)
    at org.springframework.data.neo4j.repository.query.AbstractGraphRepositoryQuery.execute(AbstractGraphRepositoryQuery.java:52)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:605)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$invoke$3(RepositoryFactorySupport.java:595)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:595)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
    at com.example.demo.$Proxy97.findAsKotlinDto(Unknown Source)
    at com.example.demo.DemoApplication.main(DemoApplication.java:24)
    Caused by: java.lang.ClassCastException: class java.lang.String cannot be cast to class java.time.LocalDateTime (java.lang.String and java.time.LocalDateTime are in module java.base of loader 'bootstrap')
    at com.example.demo.EventDtoKotlin_Instantiator_5tss1f.newInstance(Unknown Source)
    at org.springframework.data.convert.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(ClassGeneratingEntityInstantiator.java:226)
    ... 31 more


    I tried to wrap e.timestamp in localdatetime() without success:



    MATCH (e:Event) RETURN id(e) AS id, localdatetime(e.timestamp) AS timestamp, e.name AS name



    // with MATCH (e:Event) RETURN id(e) AS id, localdatetime(e.timestamp) AS timestamp, e.name AS name

    Exception in thread "main" java.lang.ClassCastException: class java.time.LocalDateTime cannot be cast to class java.lang.String (java.time.LocalDateTime and java.lang.String are in module java.base of loader 'bootstrap')
    at org.neo4j.ogm.typeconversion.LocalDateTimeStringConverter.toEntityAttribute(LocalDateTimeStringConverter.java:25)
    at org.neo4j.ogm.metadata.FieldInfo.write(FieldInfo.java:368)
    at org.neo4j.ogm.context.SingleUseEntityMapper.writeProperty(SingleUseEntityMapper.java:143)
    at org.neo4j.ogm.context.SingleUseEntityMapper.setPropertiesOnEntity(SingleUseEntityMapper.java:99)
    at org.neo4j.ogm.context.SingleUseEntityMapper.map(SingleUseEntityMapper.java:92)
    at org.springframework.data.neo4j.repository.query.CustomResultConverter.convert(CustomResultConverter.java:80)
    at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:224)
    at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.lambda$and$0(ResultProcessor.java:210)
    at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:224)
    at org.springframework.data.repository.query.ResultProcessor.processResult(ResultProcessor.java:166)
    at org.springframework.data.neo4j.repository.query.GraphRepositoryQuery.doExecute(GraphRepositoryQuery.java:72)
    at org.springframework.data.neo4j.repository.query.AbstractGraphRepositoryQuery.execute(AbstractGraphRepositoryQuery.java:52)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:605)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$invoke$3(RepositoryFactorySupport.java:595)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:595)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
    at com.example.demo.$Proxy97.findAsJavaDto(Unknown Source)
    at com.example.demo.DemoApplication.main(DemoApplication.java:23)


    Repro



    Create a Spring Initializer project with Gradle and replace the build.gradle with the following content:



    build.gradle



    plugins {
    id "org.jetbrains.kotlin.jvm" version "1.3.11"

    id("io.spring.dependency-management") version "1.0.6.RELEASE"
    id("org.springframework.boot") version "2.1.1.RELEASE"
    id("org.jetbrains.kotlin.plugin.spring") version "1.3.11"
    id("org.jetbrains.kotlin.plugin.noarg") version "1.3.11"
    }

    repositories {
    jcenter()
    }
    sourceCompatibility = 11
    targetCompatibility = 11

    ext['jackson.version'] = '2.9.8'

    noArg {
    annotation("org.neo4j.ogm.annotation.NodeEntity")
    annotation("org.neo4j.ogm.annotation.RelationshipEntity")
    annotation("org.springframework.data.neo4j.annotation.QueryResult")
    }

    compileKotlin {
    kotlinOptions {
    jvmTarget = 1.8
    javaParameters = true
    }
    }


    dependencies {
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    implementation('org.springframework.boot:spring-boot-starter-json')
    // jackson kotlin classes support
    implementation('com.fasterxml.jackson.module:jackson-module-kotlin')

    implementation('org.springframework.boot:spring-boot-starter-data-neo4j')
    runtimeOnly('org.neo4j:neo4j:3.5.1')
    runtimeOnly('org.neo4j:neo4j-ogm-embedded-driver:3.1.5')

    compileOnly('org.projectlombok:lombok')
    annotationProcessor('org.projectlombok:lombok')
    }


    DemoApplication.java



    package com.example.demo;

    import com.fasterxml.jackson.databind.SerializationFeature;
    import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
    import com.fasterxml.jackson.module.kotlin.KotlinModule;
    import lombok.val;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;

    import java.time.LocalDateTime;
    import java.util.Objects;

    @SpringBootApplication
    public class DemoApplication {
    public static void main(String args) {
    var ctx = SpringApplication.run(DemoApplication.class, args);
    setupNeo4jJavaTimeSupport();
    var repo = ctx.getBean(EventRepo.class);

    var e = repo.save(new Event(null, LocalDateTime.now(), "test!"));
    System.out.println();
    System.out.println("e = " + e);
    System.out.println("java: " + Objects.requireNonNull(repo.findAsJavaDto()));
    System.out.println("kotlin" + Objects.requireNonNull(repo.findAsKotlinDto()));
    }

    private static void setupNeo4jJavaTimeSupport() {
    // see https://stackoverflow.com/a/52475719
    var ogmObjectMapper = org.neo4j.ogm.config.ObjectMapperFactory.objectMapper();
    ogmObjectMapper.registerModule(new JavaTimeModule());
    ogmObjectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

    ogmObjectMapper.registerModule(new KotlinModule());
    }
    }









    share|improve this question



























      0












      0








      0








      I'm struggling to create a projection of a node entity Event with a Kotlin class using Spring Data Neo4j's @QueryResult and a custom @Query.



      NodeEntity: Event.java



      @NodeEntity
      // getter, setter, ... boilerplate (lombok)
      @Data @NoArgsConstructor @AllArgsConstructor
      class Event {
      @Id
      @GeneratedValue
      private Long id;
      private LocalDateTime timestamp;
      private String name;
      }


      Repo: EventRepo.java



      @Repository
      interface EventRepo extends Neo4jRepository<Event, Long> {
      // works
      @Query("MATCH (e:Event) " +
      "RETURN id(e) AS id, e.timestamp AS timestamp, e.name AS name")
      EventDtoJava findAsJavaDto();

      // meh
      @Query("MATCH (e:Event) " +
      "RETURN id(e) AS id, e.timestamp AS timestamp, e.name AS name")
      EventDtoKotlin findAsKotlinDto();
      }


      Projections: Java and Kotlin version



      // Projection with a Java class: works
      @QueryResult
      // getter, setter, ... boilerplate (lombok)
      @Data
      class EventDtoJava {
      private Long id;
      private LocalDateTime timestamp;
      private String name;
      }


      // Projection with a Kotlin class: meh
      @QueryResult
      data class EventDtoKotlin(
      var id: Long,
      var timestamp: LocalDateTime,
      var name: String
      )


      The exactly same query that worked for EventDtoJava (EventRepo.findAsJavaDto()) fails with the Kotlin class (EventRepo.findAsKotlinDto()).



      As a workaround I could use Java DTOs but this doesn't solve the underlying issue.



      As suggested in https://stackoverflow.com/a/52475719 I already added java.time support to Neo4j's ObjectMapper.



      I suspected that com.fasterxml.jackson.module:jackson-module-kotlin was missing from their ObjectMapper, but this changed nothing.



      Edit: The exception can also be triggered by creating an all args constructor in EventDtoJava.



      MATCH (e:Event) RETURN id(e) AS id, e.timestamp AS timestamp, e.name AS name



      Exception in thread "main" org.springframework.data.mapping.model.MappingInstantiationException: Failed to instantiate com.example.demo.EventDtoKotlin using constructor fun <init>(kotlin.Long, java.time.LocalDateTime, kotlin.String): com.example.demo.EventDtoKotlin with arguments 0,2019-01-03T15:11:04.581095,test!
      at org.springframework.data.convert.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(ClassGeneratingEntityInstantiator.java:228)
      at org.springframework.data.convert.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:84)
      at org.springframework.data.neo4j.conversion.Neo4jOgmEntityInstantiatorAdapter.createInstance(Neo4jOgmEntityInstantiatorAdapter.java:58)
      at org.springframework.data.neo4j.repository.query.QueryResultInstantiator.createInstance(QueryResultInstantiator.java:52)
      at org.neo4j.ogm.metadata.reflect.EntityFactory.instantiate(EntityFactory.java:121)
      at org.neo4j.ogm.metadata.reflect.EntityFactory.newObject(EntityFactory.java:90)
      at org.neo4j.ogm.context.SingleUseEntityMapper.map(SingleUseEntityMapper.java:91)
      at org.springframework.data.neo4j.repository.query.CustomResultConverter.convert(CustomResultConverter.java:80)
      at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:224)
      at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.lambda$and$0(ResultProcessor.java:210)
      at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:224)
      at org.springframework.data.repository.query.ResultProcessor.processResult(ResultProcessor.java:166)
      at org.springframework.data.neo4j.repository.query.GraphRepositoryQuery.doExecute(GraphRepositoryQuery.java:72)
      at org.springframework.data.neo4j.repository.query.AbstractGraphRepositoryQuery.execute(AbstractGraphRepositoryQuery.java:52)
      at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:605)
      at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$invoke$3(RepositoryFactorySupport.java:595)
      at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:595)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
      at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
      at com.example.demo.$Proxy97.findAsKotlinDto(Unknown Source)
      at com.example.demo.DemoApplication.main(DemoApplication.java:24)
      Caused by: java.lang.ClassCastException: class java.lang.String cannot be cast to class java.time.LocalDateTime (java.lang.String and java.time.LocalDateTime are in module java.base of loader 'bootstrap')
      at com.example.demo.EventDtoKotlin_Instantiator_5tss1f.newInstance(Unknown Source)
      at org.springframework.data.convert.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(ClassGeneratingEntityInstantiator.java:226)
      ... 31 more


      I tried to wrap e.timestamp in localdatetime() without success:



      MATCH (e:Event) RETURN id(e) AS id, localdatetime(e.timestamp) AS timestamp, e.name AS name



      // with MATCH (e:Event) RETURN id(e) AS id, localdatetime(e.timestamp) AS timestamp, e.name AS name

      Exception in thread "main" java.lang.ClassCastException: class java.time.LocalDateTime cannot be cast to class java.lang.String (java.time.LocalDateTime and java.lang.String are in module java.base of loader 'bootstrap')
      at org.neo4j.ogm.typeconversion.LocalDateTimeStringConverter.toEntityAttribute(LocalDateTimeStringConverter.java:25)
      at org.neo4j.ogm.metadata.FieldInfo.write(FieldInfo.java:368)
      at org.neo4j.ogm.context.SingleUseEntityMapper.writeProperty(SingleUseEntityMapper.java:143)
      at org.neo4j.ogm.context.SingleUseEntityMapper.setPropertiesOnEntity(SingleUseEntityMapper.java:99)
      at org.neo4j.ogm.context.SingleUseEntityMapper.map(SingleUseEntityMapper.java:92)
      at org.springframework.data.neo4j.repository.query.CustomResultConverter.convert(CustomResultConverter.java:80)
      at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:224)
      at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.lambda$and$0(ResultProcessor.java:210)
      at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:224)
      at org.springframework.data.repository.query.ResultProcessor.processResult(ResultProcessor.java:166)
      at org.springframework.data.neo4j.repository.query.GraphRepositoryQuery.doExecute(GraphRepositoryQuery.java:72)
      at org.springframework.data.neo4j.repository.query.AbstractGraphRepositoryQuery.execute(AbstractGraphRepositoryQuery.java:52)
      at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:605)
      at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$invoke$3(RepositoryFactorySupport.java:595)
      at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:595)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
      at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
      at com.example.demo.$Proxy97.findAsJavaDto(Unknown Source)
      at com.example.demo.DemoApplication.main(DemoApplication.java:23)


      Repro



      Create a Spring Initializer project with Gradle and replace the build.gradle with the following content:



      build.gradle



      plugins {
      id "org.jetbrains.kotlin.jvm" version "1.3.11"

      id("io.spring.dependency-management") version "1.0.6.RELEASE"
      id("org.springframework.boot") version "2.1.1.RELEASE"
      id("org.jetbrains.kotlin.plugin.spring") version "1.3.11"
      id("org.jetbrains.kotlin.plugin.noarg") version "1.3.11"
      }

      repositories {
      jcenter()
      }
      sourceCompatibility = 11
      targetCompatibility = 11

      ext['jackson.version'] = '2.9.8'

      noArg {
      annotation("org.neo4j.ogm.annotation.NodeEntity")
      annotation("org.neo4j.ogm.annotation.RelationshipEntity")
      annotation("org.springframework.data.neo4j.annotation.QueryResult")
      }

      compileKotlin {
      kotlinOptions {
      jvmTarget = 1.8
      javaParameters = true
      }
      }


      dependencies {
      implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
      implementation('org.springframework.boot:spring-boot-starter-json')
      // jackson kotlin classes support
      implementation('com.fasterxml.jackson.module:jackson-module-kotlin')

      implementation('org.springframework.boot:spring-boot-starter-data-neo4j')
      runtimeOnly('org.neo4j:neo4j:3.5.1')
      runtimeOnly('org.neo4j:neo4j-ogm-embedded-driver:3.1.5')

      compileOnly('org.projectlombok:lombok')
      annotationProcessor('org.projectlombok:lombok')
      }


      DemoApplication.java



      package com.example.demo;

      import com.fasterxml.jackson.databind.SerializationFeature;
      import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
      import com.fasterxml.jackson.module.kotlin.KotlinModule;
      import lombok.val;
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;

      import java.time.LocalDateTime;
      import java.util.Objects;

      @SpringBootApplication
      public class DemoApplication {
      public static void main(String args) {
      var ctx = SpringApplication.run(DemoApplication.class, args);
      setupNeo4jJavaTimeSupport();
      var repo = ctx.getBean(EventRepo.class);

      var e = repo.save(new Event(null, LocalDateTime.now(), "test!"));
      System.out.println();
      System.out.println("e = " + e);
      System.out.println("java: " + Objects.requireNonNull(repo.findAsJavaDto()));
      System.out.println("kotlin" + Objects.requireNonNull(repo.findAsKotlinDto()));
      }

      private static void setupNeo4jJavaTimeSupport() {
      // see https://stackoverflow.com/a/52475719
      var ogmObjectMapper = org.neo4j.ogm.config.ObjectMapperFactory.objectMapper();
      ogmObjectMapper.registerModule(new JavaTimeModule());
      ogmObjectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

      ogmObjectMapper.registerModule(new KotlinModule());
      }
      }









      share|improve this question
















      I'm struggling to create a projection of a node entity Event with a Kotlin class using Spring Data Neo4j's @QueryResult and a custom @Query.



      NodeEntity: Event.java



      @NodeEntity
      // getter, setter, ... boilerplate (lombok)
      @Data @NoArgsConstructor @AllArgsConstructor
      class Event {
      @Id
      @GeneratedValue
      private Long id;
      private LocalDateTime timestamp;
      private String name;
      }


      Repo: EventRepo.java



      @Repository
      interface EventRepo extends Neo4jRepository<Event, Long> {
      // works
      @Query("MATCH (e:Event) " +
      "RETURN id(e) AS id, e.timestamp AS timestamp, e.name AS name")
      EventDtoJava findAsJavaDto();

      // meh
      @Query("MATCH (e:Event) " +
      "RETURN id(e) AS id, e.timestamp AS timestamp, e.name AS name")
      EventDtoKotlin findAsKotlinDto();
      }


      Projections: Java and Kotlin version



      // Projection with a Java class: works
      @QueryResult
      // getter, setter, ... boilerplate (lombok)
      @Data
      class EventDtoJava {
      private Long id;
      private LocalDateTime timestamp;
      private String name;
      }


      // Projection with a Kotlin class: meh
      @QueryResult
      data class EventDtoKotlin(
      var id: Long,
      var timestamp: LocalDateTime,
      var name: String
      )


      The exactly same query that worked for EventDtoJava (EventRepo.findAsJavaDto()) fails with the Kotlin class (EventRepo.findAsKotlinDto()).



      As a workaround I could use Java DTOs but this doesn't solve the underlying issue.



      As suggested in https://stackoverflow.com/a/52475719 I already added java.time support to Neo4j's ObjectMapper.



      I suspected that com.fasterxml.jackson.module:jackson-module-kotlin was missing from their ObjectMapper, but this changed nothing.



      Edit: The exception can also be triggered by creating an all args constructor in EventDtoJava.



      MATCH (e:Event) RETURN id(e) AS id, e.timestamp AS timestamp, e.name AS name



      Exception in thread "main" org.springframework.data.mapping.model.MappingInstantiationException: Failed to instantiate com.example.demo.EventDtoKotlin using constructor fun <init>(kotlin.Long, java.time.LocalDateTime, kotlin.String): com.example.demo.EventDtoKotlin with arguments 0,2019-01-03T15:11:04.581095,test!
      at org.springframework.data.convert.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(ClassGeneratingEntityInstantiator.java:228)
      at org.springframework.data.convert.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:84)
      at org.springframework.data.neo4j.conversion.Neo4jOgmEntityInstantiatorAdapter.createInstance(Neo4jOgmEntityInstantiatorAdapter.java:58)
      at org.springframework.data.neo4j.repository.query.QueryResultInstantiator.createInstance(QueryResultInstantiator.java:52)
      at org.neo4j.ogm.metadata.reflect.EntityFactory.instantiate(EntityFactory.java:121)
      at org.neo4j.ogm.metadata.reflect.EntityFactory.newObject(EntityFactory.java:90)
      at org.neo4j.ogm.context.SingleUseEntityMapper.map(SingleUseEntityMapper.java:91)
      at org.springframework.data.neo4j.repository.query.CustomResultConverter.convert(CustomResultConverter.java:80)
      at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:224)
      at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.lambda$and$0(ResultProcessor.java:210)
      at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:224)
      at org.springframework.data.repository.query.ResultProcessor.processResult(ResultProcessor.java:166)
      at org.springframework.data.neo4j.repository.query.GraphRepositoryQuery.doExecute(GraphRepositoryQuery.java:72)
      at org.springframework.data.neo4j.repository.query.AbstractGraphRepositoryQuery.execute(AbstractGraphRepositoryQuery.java:52)
      at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:605)
      at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$invoke$3(RepositoryFactorySupport.java:595)
      at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:595)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
      at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
      at com.example.demo.$Proxy97.findAsKotlinDto(Unknown Source)
      at com.example.demo.DemoApplication.main(DemoApplication.java:24)
      Caused by: java.lang.ClassCastException: class java.lang.String cannot be cast to class java.time.LocalDateTime (java.lang.String and java.time.LocalDateTime are in module java.base of loader 'bootstrap')
      at com.example.demo.EventDtoKotlin_Instantiator_5tss1f.newInstance(Unknown Source)
      at org.springframework.data.convert.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(ClassGeneratingEntityInstantiator.java:226)
      ... 31 more


      I tried to wrap e.timestamp in localdatetime() without success:



      MATCH (e:Event) RETURN id(e) AS id, localdatetime(e.timestamp) AS timestamp, e.name AS name



      // with MATCH (e:Event) RETURN id(e) AS id, localdatetime(e.timestamp) AS timestamp, e.name AS name

      Exception in thread "main" java.lang.ClassCastException: class java.time.LocalDateTime cannot be cast to class java.lang.String (java.time.LocalDateTime and java.lang.String are in module java.base of loader 'bootstrap')
      at org.neo4j.ogm.typeconversion.LocalDateTimeStringConverter.toEntityAttribute(LocalDateTimeStringConverter.java:25)
      at org.neo4j.ogm.metadata.FieldInfo.write(FieldInfo.java:368)
      at org.neo4j.ogm.context.SingleUseEntityMapper.writeProperty(SingleUseEntityMapper.java:143)
      at org.neo4j.ogm.context.SingleUseEntityMapper.setPropertiesOnEntity(SingleUseEntityMapper.java:99)
      at org.neo4j.ogm.context.SingleUseEntityMapper.map(SingleUseEntityMapper.java:92)
      at org.springframework.data.neo4j.repository.query.CustomResultConverter.convert(CustomResultConverter.java:80)
      at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:224)
      at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.lambda$and$0(ResultProcessor.java:210)
      at org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:224)
      at org.springframework.data.repository.query.ResultProcessor.processResult(ResultProcessor.java:166)
      at org.springframework.data.neo4j.repository.query.GraphRepositoryQuery.doExecute(GraphRepositoryQuery.java:72)
      at org.springframework.data.neo4j.repository.query.AbstractGraphRepositoryQuery.execute(AbstractGraphRepositoryQuery.java:52)
      at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:605)
      at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$invoke$3(RepositoryFactorySupport.java:595)
      at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:595)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
      at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
      at com.example.demo.$Proxy97.findAsJavaDto(Unknown Source)
      at com.example.demo.DemoApplication.main(DemoApplication.java:23)


      Repro



      Create a Spring Initializer project with Gradle and replace the build.gradle with the following content:



      build.gradle



      plugins {
      id "org.jetbrains.kotlin.jvm" version "1.3.11"

      id("io.spring.dependency-management") version "1.0.6.RELEASE"
      id("org.springframework.boot") version "2.1.1.RELEASE"
      id("org.jetbrains.kotlin.plugin.spring") version "1.3.11"
      id("org.jetbrains.kotlin.plugin.noarg") version "1.3.11"
      }

      repositories {
      jcenter()
      }
      sourceCompatibility = 11
      targetCompatibility = 11

      ext['jackson.version'] = '2.9.8'

      noArg {
      annotation("org.neo4j.ogm.annotation.NodeEntity")
      annotation("org.neo4j.ogm.annotation.RelationshipEntity")
      annotation("org.springframework.data.neo4j.annotation.QueryResult")
      }

      compileKotlin {
      kotlinOptions {
      jvmTarget = 1.8
      javaParameters = true
      }
      }


      dependencies {
      implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
      implementation('org.springframework.boot:spring-boot-starter-json')
      // jackson kotlin classes support
      implementation('com.fasterxml.jackson.module:jackson-module-kotlin')

      implementation('org.springframework.boot:spring-boot-starter-data-neo4j')
      runtimeOnly('org.neo4j:neo4j:3.5.1')
      runtimeOnly('org.neo4j:neo4j-ogm-embedded-driver:3.1.5')

      compileOnly('org.projectlombok:lombok')
      annotationProcessor('org.projectlombok:lombok')
      }


      DemoApplication.java



      package com.example.demo;

      import com.fasterxml.jackson.databind.SerializationFeature;
      import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
      import com.fasterxml.jackson.module.kotlin.KotlinModule;
      import lombok.val;
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;

      import java.time.LocalDateTime;
      import java.util.Objects;

      @SpringBootApplication
      public class DemoApplication {
      public static void main(String args) {
      var ctx = SpringApplication.run(DemoApplication.class, args);
      setupNeo4jJavaTimeSupport();
      var repo = ctx.getBean(EventRepo.class);

      var e = repo.save(new Event(null, LocalDateTime.now(), "test!"));
      System.out.println();
      System.out.println("e = " + e);
      System.out.println("java: " + Objects.requireNonNull(repo.findAsJavaDto()));
      System.out.println("kotlin" + Objects.requireNonNull(repo.findAsKotlinDto()));
      }

      private static void setupNeo4jJavaTimeSupport() {
      // see https://stackoverflow.com/a/52475719
      var ogmObjectMapper = org.neo4j.ogm.config.ObjectMapperFactory.objectMapper();
      ogmObjectMapper.registerModule(new JavaTimeModule());
      ogmObjectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

      ogmObjectMapper.registerModule(new KotlinModule());
      }
      }






      kotlin neo4j spring-data-neo4j






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 3 at 16:45







      ingmak

















      asked Jan 3 at 15:08









      ingmakingmak

      6016




      6016
























          0






          active

          oldest

          votes












          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54024927%2fspring-boot-data-neo4j-neo4j-cannot-create-queryresult-with-a-kotlin-class%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54024927%2fspring-boot-data-neo4j-neo4j-cannot-create-queryresult-with-a-kotlin-class%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          The term 'EXEC' is not recognized as the name of a cmdlet Powershell

          NPM command prompt closes immediately [closed]

          Error binding properties and functions in emscripten