【发布时间】:2016-09-08 09:36:46
【问题描述】:
我正在尝试使用 OGM 在 Neo4j 中实现多租户。我最喜欢的解决方案是使用标签来标记具有租户 ID 的实体。不幸的是,我无法让标签在 Scala 中工作。首先,我创建了这样的实体:
trait Entity {
@GraphId
@Property
var graphId: java.lang.Long = _
}
@NodeEntity
class Tenant extends Entity {
@Property
var name: String = _
}
@NodeEntity
class Project extends Entity {
@Property
var name: String = _
@Relationship(`type` = "TENANT", direction = Relationship.OUTGOING)
var tenant: Tenant = _
@Labels
val labels: java.util.Collection[String] = new java.util.ArrayList[String]()
def this(name: String, tenant: Tenant) {
this()
this.labels.add(tanant.uuid.toString)
}
def hasLabel(label: String): Boolean = {
this.labels.contains(label)
}
}
我的仓库只有一个简单的保存方法
abstract class Repository[Model <: Entity] {
def save(entity: Model): Model = {
val session = getSession()
session.save(entity)
entity
}
}
我使用嵌入式 Neo4j 数据库创建了一个简单的测试,但最后一个断言失败并返回 false(这意味着添加的标签未持久化)。
class ProjectSuite extends BaseSuite with Neo4jOgmTestSuite {
"Project Model" should {
"save properly with Tenant label" in {
val tenant = new Tenant("TestTenant")
TanantRepository.save(tenant)
val project = new Project("TestProject", tenant)
ProjectRepository.save(project)
assert(project.hasLabel(tenant.uuid.toString))
val loadedProject = ProjectRepository.findById(project.uuid)
assert(loadedProject isDefined)
assert(loadedProject.get.hasLabel(tenant.uuid.toString))
}
}
}
知道我在这里缺少什么吗?
【问题讨论】:
-
旁注:去过那里,做过那个,走了另一条路。使用租户 ID 作为标签意味着您必须为每个租户生成特定的 Cypher 查询,因为您不能使用占位符作为标签(因为它们用于计算执行计划)。所以它有点难看,你很快就会填满查询缓存(它们被解析/预编译/可能会计算执行计划),因为每个租户的每个查询都有一个版本。
-
代码看起来不错,虽然我可能错过了一些东西,因为我用 Java 和 Kotlin 编写的代码比 Scala 多。 (我应该改变它;))。你能发送一个失败的样本,我会为你调试吗?我在 OGM 中实现了标签功能 - jasper@graphaware.com
-
@Frank 除了这两个之外的任何其他选项(你在用什么?):graphaware.com/neo4j/2015/01/16/…
-
@jasper-blues 是的,可以这样做。我将使用示例代码创建一个新的 github 存储库。准备好后,我会向您发送消息。
-
@Alebon 我们只保留了实体节点和
Tenant节点之间的关系。查询总是从检查“主”节点是否属于租户开始。