Neo4jRepository 从 Kotlin 数据中保存空节点 class
Neo4jRepository saves empty node from Kotlin data class
我有一个用于 Neo4j 节点的 Kotlin 数据 class 节点:
@NodeEntity
data class MyNode (
@Id @GeneratedValue var dbId: Long? = null,
@Index(unique = true) val name: String,
val description: String
)
和一个 Spring 存储库:
interface MyNodesRepository : Neo4jRepository<MyNode, Long>
然后,当我通过这个存储库将一个节点保存到数据库中时,它是空的,没有任何属性:
val node = MyNode(null, "name 1", "lorem ipsum")
myNodesRepository.save(node)
在 save(node)
调用之后,node.dbId
被设置为 Neo4j 的内部 ID,即它在 save()
之前为空,之后有一个值。我也可以在 Neo4j 浏览器中看到该节点,但它没有名称和描述属性。
之后,当我尝试加载所有节点时,调用因 InvalidDataAccessApiUsageException
而崩溃,因为它无法 deserialize/map 具有 null/missing 名称和描述的节点:
val allNodes = myNodesRepository.findAll()
如果我将自定义保存方法添加到我的存储库,在那里我使用 CQL 查询手动创建节点,那么一切正常。
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)
}
现在 findAll()
加载我新创建的 and/or 更新节点。
我正在使用 org.springframework.boot:spring-boot-starter-data-neo4j:2.1.6.RELEASE
,这是在 Spring Boot CLI 应用程序中,因此没有 Web 服务器和 RestControllers。
我做错了什么?
编辑: 现在在 Neo4j OGM 3.1.13
中解决了这个问题
编辑:这在 Neo4j OGM 3.1.13 中已经解决,不再需要下面的解决方法。
原始答案
经过几天的调试,Neo4j OGM 中似乎存在一个错误,用于 Kotlin 数据 类,它不保存 val
属性——数据 类 和正常类。因此从 val
属性更改:
@NodeEntity
data class MyNode (
@Id @GeneratedValue var dbId: Long? = null,
@Index(unique = true) val name: String,
val description: String
)
所有 var
属性:
@NodeEntity
data class MyNode (
@Id @GeneratedValue var dbId: Long? = null,
@Index(unique = true) var name: String,
var description: String
)
有效。现在保存和加载都有效,但它不是惯用的 Kotlin。
所以至少我们有一个解决方法。
我有一个用于 Neo4j 节点的 Kotlin 数据 class 节点:
@NodeEntity
data class MyNode (
@Id @GeneratedValue var dbId: Long? = null,
@Index(unique = true) val name: String,
val description: String
)
和一个 Spring 存储库:
interface MyNodesRepository : Neo4jRepository<MyNode, Long>
然后,当我通过这个存储库将一个节点保存到数据库中时,它是空的,没有任何属性:
val node = MyNode(null, "name 1", "lorem ipsum")
myNodesRepository.save(node)
在 save(node)
调用之后,node.dbId
被设置为 Neo4j 的内部 ID,即它在 save()
之前为空,之后有一个值。我也可以在 Neo4j 浏览器中看到该节点,但它没有名称和描述属性。
之后,当我尝试加载所有节点时,调用因 InvalidDataAccessApiUsageException
而崩溃,因为它无法 deserialize/map 具有 null/missing 名称和描述的节点:
val allNodes = myNodesRepository.findAll()
如果我将自定义保存方法添加到我的存储库,在那里我使用 CQL 查询手动创建节点,那么一切正常。
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)
}
现在 findAll()
加载我新创建的 and/or 更新节点。
我正在使用 org.springframework.boot:spring-boot-starter-data-neo4j:2.1.6.RELEASE
,这是在 Spring Boot CLI 应用程序中,因此没有 Web 服务器和 RestControllers。
我做错了什么?
编辑: 现在在 Neo4j OGM 3.1.13
中解决了这个问题编辑:这在 Neo4j OGM 3.1.13 中已经解决,不再需要下面的解决方法。
原始答案
经过几天的调试,Neo4j OGM 中似乎存在一个错误,用于 Kotlin 数据 类,它不保存 val
属性——数据 类 和正常类。因此从 val
属性更改:
@NodeEntity
data class MyNode (
@Id @GeneratedValue var dbId: Long? = null,
@Index(unique = true) val name: String,
val description: String
)
所有 var
属性:
@NodeEntity
data class MyNode (
@Id @GeneratedValue var dbId: Long? = null,
@Index(unique = true) var name: String,
var description: String
)
有效。现在保存和加载都有效,但它不是惯用的 Kotlin。
所以至少我们有一个解决方法。