gpt4 book ai didi

Neo4j - OGM 在 Kotlin 中抛出的不是实体

转载 作者:行者123 更新时间:2023-12-04 23:36:50 25 4
gpt4 key购买 nike

正如上面的图块,我一直在尝试使用 neo4j-ogm 和 kotlin,但没有成功。如果我尝试保留我的数据,Neo4j 会抛出异常,“类 xxxx 不是有效实体”。

package com.asofttz.micros.administrator.users.testmodels

import org.neo4j.ogm.annotation.GeneratedValue
import org.neo4j.ogm.annotation.Id
import org.neo4j.ogm.annotation.NodeEntity
import org.neo4j.ogm.annotation.Relationship

@NodeEntity
class Actor(var name: String = "") {

@Id
@GeneratedValue
open var id: Long? = null

@Relationship(type = "ACTS_IN", direction = "OUTGOING")
open val movies = hashSetOf<Movie>()

fun actsIn(movie: Movie) {
movies.add(movie)
movie.actors.plus(this)
}
}
@NodeEntity
class Movie(var title: String = "", var released: Int = 2000) {

@Id
@GeneratedValue
open var id: Long? = null
@Relationship(type = "ACTS_IN", direction = "INCOMING")
open var actors = setOf<Actor>()
}

有办法吗?是否有使用 kotlin 将数据保存到 Neo4j 数据库的替代方法?

纽:B。我正在使用 kotlin 版本 1.2.60 和 Neo4j-OGM v3.2.1

更新
下面是我的其余代码
import com.asofttz.micros.administrator.users.testmodels.Actor
import com.asofttz.micros.administrator.users.testmodels.Movie
import org.neo4j.ogm.config.Configuration
import org.neo4j.ogm.session.SessionFactory
import java.util.*


object Neo4j {
val configuration = Configuration.Builder()
.uri("bolt://localhost")
.credentials("neo4j", "password")
.build()

val sessionFactory = SessionFactory(configuration, "test.movies.domain")

fun save() {

val session = sessionFactory.openSession()

val movie = Movie("The Matrix", 1999)

session.save(movie)

val matrix = session.load(Movie::class.java, movie.id)
for (actor in matrix.actors) {
println("Actor: " + actor.name)
}
}
}

build.gradle 文件看起来像这样
apply plugin: 'kotlin'
apply plugin: 'application'
apply plugin: "org.jetbrains.kotlin.plugin.noarg"

repositories {
jcenter()
mavenCentral()
maven { url "http://dl.bintray.com/kotlin/ktor" }
maven { url "https://dl.bintray.com/kotlin/kontlinx" }
}

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

dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
compile "io.ktor:ktor:$ktor_version"
compile "io.ktor:ktor-server-netty:$ktor_version"

compile project(":asoftlibs:micros:administrator:users:users-jvm")

compile 'org.neo4j:neo4j-ogm-core:3.1.2'
compile 'org.neo4j:neo4j-ogm-bolt-driver:3.1.2'
}

kotlin {
experimental {
coroutines "enable"
}
}

compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
sourceCompatibility = "1.8"

我得到类'com.asofttz.micros.administrator.users.testmodels.Movie is not a valid entity' 进一步的帮助将不胜感激。

注意:我还尝试在没有婴儿车构造器的情况下打开电影类,但 id ddnt 也有帮助。另一次尝试是更改neo4j-ogm的版本,所以我测试了2.1.5、3.0.1和3.1.2。没有成功

最佳答案

编辑:没有解释的 super 简短回答是:在您的示例中,您为类扫描配置了错误的包。您正在使用 val sessionFactory = SessionFactory(configuration, "test.movies.domain") 打开 session 但它必须是 val sessionFactory = SessionFactory(configuration, "com.asofttz.micros.administrator.users.testmodels")从你的模型的包声明来看。但此外,请参阅我的较长版本以获取一些最佳实践和解释:

在此处找到完整且有效的示例作为要点:Minimal Kotlin/Gradle Example for Neo4j OGM

让我带你了解一下:

build.gradle ,定义 No-arg compiler plugin作为构建脚本依赖项。

buildscript {
dependencies {
classpath "org.jetbrains.kotlin:kotlin-noarg:1.2.51"
}
}

而不是使用 noArg块来定义应该为哪些类合成无参数构造函数:
noArg {
annotation("org.neo4j.ogm.annotation.NodeEntity")
annotation("org.neo4j.ogm.annotation.RelationshipEntity")
}

这意味着:所有用 @NodeEntity 注释的类和 @RelationshipEntity应该有一个合成的无参数构造函数。

我完全同意 Jasper 的观点,这是比默认域类的所有构造函数参数更好的方法,作为引用,kotlin-noarg 文档:

The no-arg compiler plugin generates an additional zero-argument constructor for classes with a specific annotation.

The generated constructor is synthetic so it can’t be directly called from Java or Kotlin, but it can be called using reflection.



关于域类:由 Neo4j OGM 映射的类不需要是最终的。但是我们不支持 final 字段,因此,没有纯粹的不可变类。这就是目前的情况。

所以这里有两个域类:
@NodeEntity
class Actor(var name: String) {

@Id
@GeneratedValue
var id: Long? = null

@Relationship(type = "ACTS_IN", direction = "OUTGOING")
var movies = mutableSetOf<Movie>()

fun actsIn(movie: Movie) {
movies.add(movie)
movie.actors.add(this)
}
}

@NodeEntity
class Movie(var title: String, var released: Int) {

@Id
@GeneratedValue
var id: Long? = null
@Relationship(type = "ACTS_IN", direction = "INCOMING")
var actors = mutableSetOf<Actor>()
}

请注意,所有字段都是 var ,不是 val .您可以安全地省略 open关键字在这里。另请注意,我确实删除了“真实”业务信息的默认参数(此处为标题和发布年份)。

我们必须特别注意集合:我删除了显式 hashSetOf而是使用 mutableSetOf .我们可以使用 #add改变集合本身。

如果您更喜欢 Kotlin 惯用的方式,请使用 setOf并利用我们的属性不再是最终的这一事实并改变字段本身:
@NodeEntity
class Actor(var name: String) {

@Id
@GeneratedValue
var id: Long? = null

@Relationship(type = "ACTS_IN", direction = "OUTGOING")
var movies = setOf<Movie>()

fun actsIn(movie: Movie) {
movies += movie
movie.actors += this
}
}

@NodeEntity
class Movie(var title: String, var released: Int) {

@Id
@GeneratedValue
var id: Long? = null
@Relationship(type = "ACTS_IN", direction = "INCOMING")
var actors = setOf<Actor>()
}

请注意:在您的原始示例中,您有一个类似 movie.actors.plus(this) 的语句。 .这不会改变集合而是创建一个新集合,就像 + 一样。集合的运算符确实如此。

在建模层面上:我个人不会在两个方向上映射关系。这迟早会咬你,就像在 JPA/ORM 世界中一样。映射您的逻辑所需的方向并分别执行其他路径查询等。

请让我知道这可不可以帮你。我正在关闭您现在创建的 GH 问题。

关于Neo4j - OGM 在 Kotlin 中抛出的不是实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52106841/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com