Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何告诉SpringDataMongoDB存储文档的嵌套字段,这些字段也是它们自己集合中的文档?_Spring_Mongodb_Kotlin_Spring Data Mongodb - Fatal编程技术网

如何告诉SpringDataMongoDB存储文档的嵌套字段,这些字段也是它们自己集合中的文档?

如何告诉SpringDataMongoDB存储文档的嵌套字段,这些字段也是它们自己集合中的文档?,spring,mongodb,kotlin,spring-data-mongodb,Spring,Mongodb,Kotlin,Spring Data Mongodb,我有两个集合名为个人和地址。这样做的目的是让某人在字段address中保留一个地址。我使用SpringDataMongoDB来持久化上述文档 我通常在Person>Address之间构建“关系”的方法是存储地址的ID并将其提供给Person对象。后来当我找到一个人时,我通过地址对象的id来解析它,瞧,我有了我的个人+地址 然而,我发现这有点麻烦,因为在我的代码中,我只想添加地址对象作为一个整体,而不仅仅是它的ID,这样我就可以处理它,同时还可以随时将它保存到存储库中 因此,我开始了一个小的单元测

我有两个集合名为
个人
地址
。这样做的目的是让某人在字段
address
中保留一个地址。我使用SpringDataMongoDB来持久化上述文档

我通常在Person>Address之间构建“关系”的方法是存储地址的ID并将其提供给Person对象。后来当我找到一个人时,我通过地址对象的id来解析它,瞧,我有了我的个人+地址

然而,我发现这有点麻烦,因为在我的代码中,我只想添加
地址
对象作为一个整体,而不仅仅是它的ID,这样我就可以处理它,同时还可以随时将它保存到存储库中

因此,我开始了一个小的单元测试,看看Spring Data MongoDB如何保存
地址
对象,如果它只是
个人
的一个字段,而不是由它自己的
存储库
保存

这就是我想到的:

import org.springframework.data.mongodb.core.mapping.Document
导入org.springframework.data.mongodb.repository.MongoRepository
导入org.springframework.stereotype.Repository
@文件(“人”)
数据类人员(
valid:String,
val name:String,
年龄:Int,
变量地址:地址
)
@文件(“地址”)
数据类地址(
valid:String,
瓦尔街:字符串?,
val编号:Int?
)
@存储库
接口PersonRepository:MongoRepository
@存储库
接口地址存储库:MongoRepository
这是单元测试——正如我所期望的那样,最后的步骤失败了:

内部类FooTest@Autowired构造函数(
私有val personRepository:personRepository,
专用val addressRepository:addressRepository
) {
@试验
有趣的‘一些实验’(){
val testPerson=人(“001”,“彼得”,25,地址(“011”,“木材编号”,12))
personRepository.save(testPerson)
val person=personRepository.findAll()[0]
assertThat(person).isNotNull
assertThat(person.address).isNotNull
资产(人、地址、街道)isEqualTo(“伐木工”)
资产(人、地址、号码)。isEqualTo(12)
//工作是因为地址刚刚复制到对象结构中
//属于“person”,未被视为独立文件
val address=addressRepository.findAll()[0]
assertThat(address.street).isEqualTo(“木材号”)//失败
assertThat(address.number).isEqualTo(12)//失败
//正如预期的那样,“地址”没有与“个人”文档一起保留。
}
}
因此,我考虑使用
AbstractMongoEventListener
截取保存过程,从Person中选择
Address
对象,然后执行
addressRepository.save(addressDocument)
,同时将一个轻量级Address对象(只有ID)放回
Person
文档中。 同样的,我也希望在相反的情况下,在查找Person并将Person和Address重新组合在一起时

@组件
类MongoSaveInterceptor(
val addressRepository:addressRepository
):AbstractMongoEventListener(){
重写onBeforeConvert(事件:BeforeConvertEvent){
val personosave=event.source
val extractedAddress=personosave.address
val idOfAddress=addressRepository.save(extractedAddress).id
personToSave.address=地址(idOfAddress,null,null)
}
覆盖AfterConvert(事件:AfterConvertEvent){
val person=event.source
val idOfAddress=person.address.id
val foundAddress=addressRepository.findById(idOfAddress)
foundAddress.ifPresent{
person.address=it
}
}
}
它就是这样工作的,可能是我的需求的一个变通解决方案

但是

我觉得必须有类似的东西已经在工作,我可能只需要找到合适的配置


这就是我被困在atm机上的地方,需要一些指导。

另一项研究表明,它是关于我必须使用的
@DBRef
()。通过这种方式,Spring Data MongoDB存储嵌入的文档类,并在从数据库加载父文档对象时解析它。

@document(“addresses”)
-这些
地址是一个不同的集合?其思想是将
个人
地址
分为两个单独的集合。请不要问原因,因为这是一个最低限度的例子,我不想用需求背后的概念细节来回答问题。我只是在读@DBRef,它看起来正是我所需要的。我会重申一个答案,如果它的工作方式,我需要它。我认为设计应该是,地址是嵌入在个人文件。这是文档模型的主要功能之一。不建议使用地址集合。看这个。它遵循的原则是,相关数据应该存储在一起,并且可以一起访问。@prasad_u这种方法的问题是,如果我想更改“地址”,我必须更改嵌入其中的每个文档中的地址,以保持一致性。我知道这是关系数据库通过设计解决的问题,但因为我希望MongoDB具有其他特性,而不是文档设计,所以除了返回到关系设计,我别无选择