Я создаю API с помощью Spring Boot и Kotlin. Я пытаюсь создать структуру следующим образом в MongoDB.
Я понимаю, что в MongoDb концепция отношений между сущностями не существует, поэтому я буду использовать стратегию встроенных документов. То есть встраивать Реюньон в Проект, а Участника в Реюньон.
У меня есть главный класс с именами 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>?
) {}
Вот где у меня проблема. Я хочу сгенерировать ObjectId для этого NewReunion
класса, чтобы каждый вложенный в него объект имел 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)
}
POST с почтальоном:
Для отправки информации я использую Почтальон, и отправляю запрос следующим образом.
Во время создания нового 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'
}