Reputation: 3373
I have a Kotlin data class node for Neo4j nodes:
@NodeEntity
data class MyNode (
@Id @GeneratedValue var dbId: Long? = null,
@Index(unique = true) val name: String,
val description: String
)
and a Spring repository:
interface MyNodesRepository : Neo4jRepository<MyNode, Long>
Then, when I save a node into the DB via this repository it is empty, without any properties:
val node = MyNode(null, "name 1", "lorem ipsum")
myNodesRepository.save(node)
after the save(node)
call, the node.dbId
is set to the Neo4j's internal id i.e. it is null before save()
and has a value afterwards. I can also see the node in the Neo4j browser, but it does not have name and description properties.
After that, when I try to load all nodes the call crashes with InvalidDataAccessApiUsageException
because it cannot deserialize/map the nodes with null/missing name and description:
val allNodes = myNodesRepository.findAll()
If I add a custom save method to my repository, where I manually create the node with CQL query, then everything works.
interface MyNodesRepository : Neo4jRepository<MyNode, Long> {
@Query(
"MERGE (mn:MyNode {name:{name}})\n" +
"ON CREATE SET m += {description:{description}}"
)
fun customSave(@Param("name") name: String, @Param("description") description: String)
}
Now the findAll()
loads my newly created and/or updated nodes.
I am using org.springframework.boot:spring-boot-starter-data-neo4j:2.1.6.RELEASE
and this is inside a Spring Boot CLI application so no web server and RestControllers.
What am I doing wrong?
EDIT: This is now solved in Neo4j OGM 3.1.13
Upvotes: 0
Views: 140
Reputation: 3373
EDIT: This is now solved in Neo4j OGM 3.1.13 and the workaround below is not needed anymore.
ORIGINAL ANSWER
After few days of debugging it looks like there is a bug in Neo4j OGM for Kotlin data classes where it does not save val
properties -- both in data classes and normal classes. So change from val
properties:
@NodeEntity
data class MyNode (
@Id @GeneratedValue var dbId: Long? = null,
@Index(unique = true) val name: String,
val description: String
)
to all var
properties:
@NodeEntity
data class MyNode (
@Id @GeneratedValue var dbId: Long? = null,
@Index(unique = true) var name: String,
var description: String
)
works. Now both saving and loading works, but it is not idiomatic Kotlin.
So at least we have a workaround.
Upvotes: 0