我有这样的位置模型(呈现专有模型的等效模拟,省略自动生成的id和其他一些字段):
@NodeEntity
class Space: Location() {
@field:Relationship(type = "SUBLOCATED_IN", direction = Relationship.OUTGOING) var subLocation: SubLocation? = null
}
@NodeEntity
abstract class SubLocation: Location() {
@field:Relationship(type = "LOCATED_IN", direction = Relationship.OUTGOING) var locatedIn: Building? = null
}
@NodeEntity
class Building: Location()
@NodeEntity
abstract class Location {
var name: String? = null
var city: String? = null
var country: String? = null
}
SubLocation
是几个不同具体类的摘要,如Office
,Desk
,Room
等,这些实现是无关紧要的。使用Location
,例如在Person
班:
@NodeEntity
class Person(
var name: String,
@JsonIgnore @Relationship(type = "WORKS_IN", direction = Relationship.OUTGOING)
var location: Location? = null
)
当我有像Person
-> Room
(SubLocation
) - > Building
这样的子图时,一切都像魅力一样。我通过Neo4jRepository
界面查询它产生一个Person
对象与location
(Person
-> SubLocation
)以及locatedIn
(SubLocation
-> Building
)正确设置:
interface PersonRepository: Neo4jRepository<Person, Long> {
@Depth(5) // exaggerated for test purposes
fun findAllByName(name: String): List<Person>
}
当我有一个子图时,问题就会显露出来
Person
-> Space
- > Room
(SubLocation
) - > Building
当我使用相同的存储库方法查询时,我只获得映射到对象的第一级关系。 Person
对象有location
设置为Space
,但Space
有subLocation
设置为null
。
我使用的是最新版本:spring-data-neo4j -> 5.1.6.RELEASE
和neo4j-ogm-core -> 3.1.8
以及neo4j:3.5.3
。
TL; DR:
spring-data-neo4j
不会自动将具有抽象类类型的@Relationship
注释字段映射到具体对象,null
被分配。
显然它可以通过自定义@Query
解决:
interface PersonRepository: Neo4jRepository<Person, Long> {
@Query(""""
MATCH g=(:Person)-[*1..3]->(:Building)
RETURN g
"""")
fun findAllByName(name: String): List<Person>
}