and*_*max 4 neo4j kotlin neo4j-ogm
就像上面的瓷砖一样,我一直在尝试使用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>()
}
Run Code Online (Sandbox Code Playgroud)
有办法吗?是否存在使用kotlin将数据保存到Neo4j数据库的替代方法?
N:乙.我使用的是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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
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"
Run Code Online (Sandbox Code Playgroud)
我得到了类'com.asofttz.micros.administrator.users.testmodels.Movie不是一个有效的实体',我们将不胜感激.
注意:我还尝试使用no pram构造函数打开电影类,但id ddnt也可以帮助.另一个尝试是改变neo4j-ogm的版本,所以我测试了2.1.5,3.0.1和3.1.2.没有成功
编辑:超简答案没有解释是:在您的示例中,您正在配置错误的类扫描包.您打开会话val sessionFactory = SessionFactory(configuration, "test.movies.domain")但需要val sessionFactory = SessionFactory(configuration, "com.asofttz.micros.administrator.users.testmodels")从模型的包声明来判断.但另外,请参阅我的更长版本以获得最佳实践和解释:
在此处找到完整且有效的示例:Neo4j OGM的最小Kotlin/Gradle示例
让我带你走过去:
在build.gradle,将No-arg编译器插件定义为构建脚本依赖项.
buildscript {
dependencies {
classpath "org.jetbrains.kotlin:kotlin-noarg:1.2.51"
}
}
Run Code Online (Sandbox Code Playgroud)
而且使用noArg块来定义哪些类应该合成无参数构造函数:
noArg {
annotation("org.neo4j.ogm.annotation.NodeEntity")
annotation("org.neo4j.ogm.annotation.RelationshipEntity")
}
Run Code Online (Sandbox Code Playgroud)
这意味着:所有类都注释了@NodeEntity并且@RelationshipEntity应该具有合成的无参数构造函数.
我绝对同意Jasper的说法,这是比默认所有域类的构造函数参数更好的方法,供参考,kotlin-noarg文档:
no-arg编译器插件为具有特定注释的类生成额外的零参数构造函数.
生成的构造函数是合成的,因此不能直接从Java或Kotlin调用,但可以使用反射调用它.
关于域类: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>()
}
Run Code Online (Sandbox Code Playgroud)
请注意,所有字段var,不是val.您可以在open此安全地省略关键字.另请注意,我确实删除了"真实"商业信息的默认参数(此处为标题和发行年份).
我们必须特别注意集合:我删除了显式hashSetOf而是使用了mutableSetOf.我们可以#add用来改变集合本身.
如果您更喜欢Kotlin惯用法,请使用setOf并利用我们的属性不再是final的事实并改变字段本身:
@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>()
}
Run Code Online (Sandbox Code Playgroud)
请注意:在您的原始示例中,您有一个类似的声明movie.actors.plus(this).这并没有发生变异的集合,但创建一个新的,完全像+换套做运营商.
在建模层面:我个人不会在两个方向上映射关系.这往往会让你迟早咬你,就像它在JPA/ORM世界中一样.映射逻辑所需的方向,并分别对路径等执行其他查询.
请让我知道这可不可以帮你.我正在关闭你现在创建的GH问题.
| 归档时间: |
|
| 查看次数: |
416 次 |
| 最近记录: |