【发布时间】:2019-04-14 01:40:28
【问题描述】:
我正在使用 Spring Boot 和 Kotlin 构建 API。我正在尝试在 MongoDB 中通过以下方式生成结构。
我知道在MongoDb中不存在实体间关系的概念,所以我会使用嵌入文档的策略。也就是说,将 Reunión 嵌入 Proyecto,将 Participant 嵌入 Reunión。
我有一个名为Proyecto 和NewProyecto 的主类,其中包含NewReunion 类型的重聚列表作为属性。我使用两个不同的类来创建和返回数据。
Proyecto.kt
@Document(collection = "proyectos")
@TypeAlias("proyecto")
data class Proyecto (
@Id
val id: String,
val nombre: String,
val area: String,
val fecha:String,
val reuniones: List<Reunion>?
){}
@Document(collection = "proyectos")
@TypeAlias("newproyecto")
data class NewProyecto (
@Id
val id: String?,//Es posiblemente nulo porqué se crea automáticamente
var nombre: String,
var area: String,
var fecha:String,
var reuniones: List<NewReunion>?
){}
现在,要创建“重聚”,我有两个班级,Reunion 和 NewReunion。对应于创建 MongoDB 嵌入文档的类是NewReunion。
NewReunion.kt
@Document
data class Reunion(
val objetivo: String,
val fecha: String,
val participantes: List<Participante>?
) {}
@Document
data class NewReunion(
var id: String? = ObjectId().toHexString(),
var fecha: String,
var participantes: List<NewParticipante>?
) {}
这就是我的问题所在。我想为这个NewReunion 类生成一个ObjectId,以便嵌入其中的每个对象都有一个id。问题是ObjectId ().ToHexString() 在构建NewReunion 类型的对象时没有生成任何值,但是objetivo 和fecha 的其他数据填充了来自请求POST 的数据.
我如何发送信息。
我通过POST发送的信息。这个请求由一个名为ProyectoController.kt的控制器处理
ProyectoController.kt
@PostMapping("/")
fun createProyecto(@RequestBody newProyecto: NewProyecto): NewProyecto = proyectoService.createProyecto(newProyecto)
ProyectoRepository.kt
interface ProyectoRepository : MongoRepository<Proyecto, String> {
fun findById(id: ObjectId): Proyecto
override fun findAll(): List<Proyecto>
fun insert(proyecto: NewProyecto): NewProyecto
fun save(proyect: Proyecto): Proyecto
fun deleteById(id: ObjectId)
}
ProyectoService.kt
@Service("proyectoService")
class ProyectoServiceImpl : ProyectoService {
@Autowired
lateinit var proyectoRepository: ProyectoRepository
//Obtener un proyecto
override fun findById(id: ObjectId): Proyecto = proyectoRepository.findById(id)
//Obtener todos los proyectos
override fun findAll(): List<Proyecto> = proyectoRepository.findAll()
//Crear un proyecto
override fun createProyecto(newProyecto: NewProyecto): NewProyecto = proyectoRepository.insert(newProyecto)
//Actualizar un proyecto
override fun updateProyecto(proyecto: Proyecto):Proyecto = proyectoRepository.save(proyecto)
//Eliminar un proyecto
override fun deleteProyecto(id:ObjectId) = proyectoRepository.deleteById(id)
}
使用 Postman 发布:
为了发送信息,我正在使用 Postman,并通过以下方式发送请求。
在创建新的Proyecto时,我返回它以查看返回结果为id=null的结果,但所有其他字段都分配了相应的值:
现在,我尝试初始化 NewReunion 类的所有构造函数参数,看看发生了什么。
data class NewReunion(
@Id
var id: String? = ObjectId().toHexString(),
var objetivo: String = "",
var fecha: String = ""
) {}
id 的值与其他值一起正确生成。就是这种行为我不明白为什么要初始化NewReunion类的构造函数参数。
参数初始化后的 POST 结果。
build.gradle
buildscript {
ext.kotlin_version = '1.2.71'
ext {
kotlinVersion = '1.2.71'
springBootVersion = '2.0.6.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}")
classpath("org.jetbrains.kotlin:kotlin-allopen:${kotlinVersion}")
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin'
apply plugin: 'kotlin-spring'
apply plugin: 'eclipse-wtp'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'war'
group = 'com.gibranlara'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
compileKotlin {
kotlinOptions {
freeCompilerArgs = ["-Xjsr305=strict"]
jvmTarget = "1.8"
}
}
compileTestKotlin {
kotlinOptions {
freeCompilerArgs = ["-Xjsr305=strict"]
jvmTarget = "1.8"
}
}
repositories {
mavenCentral()
}
configurations {
providedRuntime
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" // Required for Kotlin integration
compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
compile "org.springframework.boot:spring-boot-starter-data-mongodb"
compile 'org.springframework.boot:spring-boot-starter-web'
}
【问题讨论】:
-
如果
objetivo和fecha为空,它在哪里获取值?我认为这些例子并不完整。另外我认为这篇文章缺少有关使用过的库的信息 -
@asm0dey
objetivo和fecha在创建新实例时不应该为空,所以我没有标有?的属性。该信息来自邮递员的帖子。 -
@asm0dey 我已经编辑了我的问题以提供更多背景信息。
-
@Gibrán,我已经展示了我认为您想要实现的目标,请查看。 github.com/andre-artus/kotlin-optional-param-spring-demo 如果这看起来像你想要的,我可以在这里进一步解释。
-
酷。您可能应该编辑您的问题以反映您在 Spring Boot 中使用 Kotlin 默认参数时遇到问题。现在的问题可能对其他人没有太大帮助,这可能就是有人否决它的原因。如果您想进一步讨论这个问题,您可以在我发布的 GitHub 存储库上提出问题。或者带它去聊天。
标签: mongodb spring-mvc spring-boot kotlin