Neo4j spring 存储库无法匹配相关实体的 Id 字段
Neo4j spring repository can't match on related entity's Id field
我有一个 User
,它可以有一个或多个 Project
,其中两者之间的 BELONGS_TO
关系在 UserEntity
中保持,其中 Project
继承自。
class User {
@Id @GeneratedValue
var id : Long?
lateinit var name: String
}
class Project : UserEntity() {
lateinit var title: String
}
abstract class UserEntity {
@Id @GeneratedValue
var id : Long?
@Relationship(type="BELONGS_TO", type="OUTGOING")
lateinit var user: User
}
存储库遵循类似的模式,其中 ProjectRepository
从 UserEntityRepository
继承通用 fun findByIdAndUserId()
:
interface UserRepository: Neo4jRepository<T, Long>
interface ProjectRepository: UserEntityRepository<Project>
@NoRepositoryBean
interface UserEntityRepository<T : UserEntity> : Neo4jRepository<T, Long> {
fun findByIdAndUserId(id: Long, userId: Long): T?
}
最后是测试:
@Test
fun findByIdAndUserId() {
// Set up
val savedUser = userRepo.save(User(name = "John"))
val savedProject = projectRepo.save(Project(title="Neo4j", user=savedUser))
// Find the project
var userProject = projectsRepo.findByIdAndUserId(savedProject.id!!, savedUser.id!!)
// Verify projet was found
assertThat(userProject).isNotNull() // ** FAILS **
}
所以,findByIdAndUserId
returns null,它没有通过项目id + 用户id 找到项目。在日志中我发现了这个查询:
MATCH (n:`Project`)
WHERE n.`id` = {id_0}
MATCH (m0:`User`)
WHERE m0.`id` = {user_id_1}
MATCH (n)-[:`BELONGS_TO`]->(m0)
WITH n
RETURN n,[ [ (n)-[r_b1:`BELONGS_TO`]->(u1:`User`) | [ r_b1, u1 ] ] ], ID(n)
with params {id_0=2, user_id_1=1}
起初看起来没问题,因为项目有 id 2,用户有 id 1(我检查了 neo4j),但是 运行 这个手动查询我也得到零结果。
我发现问题在于生成的查询如何匹配 User
的 id
,它将其视为正常的 属性 而不是 ID。如果我交换
它会按预期工作
WHERE m0.`id` = {user_id_1}
与
WHERE ID(m0) = {user_id_1}
一个快速修复方法是向每个继承 UserEntityRepository
的存储库接口添加一个带有自定义 @Query 的 findByIdAndUserId
方法,但我希望避免这种重复。
有人知道这个问题的解决方法吗?这是一个错误吗?
目前 SDN 中的 id
字段没有特殊处理。这个问题在某种程度上与 Spring data neo4j : count relation By EndNode ID and the resulting issue https://jira.spring.io/browse/DATAGRAPH-1049 .
有关
我认为如果这个问题得到解决,SDN 在生成查询时会有更好的 ID 处理。
我有一个 User
,它可以有一个或多个 Project
,其中两者之间的 BELONGS_TO
关系在 UserEntity
中保持,其中 Project
继承自。
class User {
@Id @GeneratedValue
var id : Long?
lateinit var name: String
}
class Project : UserEntity() {
lateinit var title: String
}
abstract class UserEntity {
@Id @GeneratedValue
var id : Long?
@Relationship(type="BELONGS_TO", type="OUTGOING")
lateinit var user: User
}
存储库遵循类似的模式,其中 ProjectRepository
从 UserEntityRepository
继承通用 fun findByIdAndUserId()
:
interface UserRepository: Neo4jRepository<T, Long>
interface ProjectRepository: UserEntityRepository<Project>
@NoRepositoryBean
interface UserEntityRepository<T : UserEntity> : Neo4jRepository<T, Long> {
fun findByIdAndUserId(id: Long, userId: Long): T?
}
最后是测试:
@Test
fun findByIdAndUserId() {
// Set up
val savedUser = userRepo.save(User(name = "John"))
val savedProject = projectRepo.save(Project(title="Neo4j", user=savedUser))
// Find the project
var userProject = projectsRepo.findByIdAndUserId(savedProject.id!!, savedUser.id!!)
// Verify projet was found
assertThat(userProject).isNotNull() // ** FAILS **
}
所以,findByIdAndUserId
returns null,它没有通过项目id + 用户id 找到项目。在日志中我发现了这个查询:
MATCH (n:`Project`)
WHERE n.`id` = {id_0}
MATCH (m0:`User`)
WHERE m0.`id` = {user_id_1}
MATCH (n)-[:`BELONGS_TO`]->(m0)
WITH n
RETURN n,[ [ (n)-[r_b1:`BELONGS_TO`]->(u1:`User`) | [ r_b1, u1 ] ] ], ID(n)
with params {id_0=2, user_id_1=1}
起初看起来没问题,因为项目有 id 2,用户有 id 1(我检查了 neo4j),但是 运行 这个手动查询我也得到零结果。
我发现问题在于生成的查询如何匹配 User
的 id
,它将其视为正常的 属性 而不是 ID。如果我交换
WHERE m0.`id` = {user_id_1}
与
WHERE ID(m0) = {user_id_1}
一个快速修复方法是向每个继承 UserEntityRepository
的存储库接口添加一个带有自定义 @Query 的 findByIdAndUserId
方法,但我希望避免这种重复。
有人知道这个问题的解决方法吗?这是一个错误吗?
目前 SDN 中的 id
字段没有特殊处理。这个问题在某种程度上与 Spring data neo4j : count relation By EndNode ID and the resulting issue https://jira.spring.io/browse/DATAGRAPH-1049 .
我认为如果这个问题得到解决,SDN 在生成查询时会有更好的 ID 处理。