У меня есть две модели:
package com.example.timestat.models
import jakarta.persistence.*
@Entity
@Table(name = "subjects")
data class Subject(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
val id: Long,
@Column(name = "name")
val name: String,
@Column(name = "description")
val description: String,
@OneToMany(cascade = [CascadeType.ALL], fetch = FetchType.LAZY, mappedBy = "subject")
val events: List<Event> = listOf()
)
package com.example.timestat.models
import jakarta.persistence.*
import java.util.*
@Entity
@Table(name = "events")
data class Event(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
val id: Long,
@Column(name = "name")
val name: String,
@Column(name = "description")
val description: String,
@Column(name = "date")
val date: Date,
@Column(name = "approved")
val approved: Boolean,
@Column(name = "type")
val type: String,
@Column(name = "sourceHref")
val sourceHref: String,
@ManyToOne(cascade = [CascadeType.REFRESH], fetch = FetchType.EAGER)
val subject: Subject
)
И есть два контроллера:
package com.example.timestat.controllers
import com.example.timestat.models.Subject
import com.example.timestat.service.SubjectService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
@RestController
@RequestMapping("/api/subjects")
class SubjectController(@Autowired private val service: SubjectService) {
@GetMapping("")
fun getList(): List<Subject> {
return service.list()
}
@GetMapping("/{id}")
fun getById(@PathVariable id: Long): ResponseEntity<Subject> {
val subject = service.oneById(id) ?: return ResponseEntity(HttpStatus.NOT_FOUND)
return ResponseEntity(subject, HttpStatus.OK)
}
@PostMapping("")
fun create(@RequestBody subject: Subject): ResponseEntity<Subject> {
val created = service.save(subject)
return ResponseEntity(created, HttpStatus.OK)
}
@DeleteMapping("/{id}")
fun delete(@PathVariable id: Long): ResponseEntity<Subject> {
service.existsById(id) ?: return ResponseEntity(HttpStatus.NOT_FOUND)
service.delete(id)
return ResponseEntity(HttpStatus.NO_CONTENT)
}
}
package com.example.timestat.controllers
import com.example.timestat.models.Event
import com.example.timestat.service.EventService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
@RestController
@RequestMapping("/api/events")
class EventController(@Autowired private val service: EventService) {
@GetMapping("")
fun getList(): List<Event> {
return service.list()
}
@GetMapping("/{id}")
fun getById(@PathVariable id: Long): ResponseEntity<Event> {
val event = service.oneById(id) ?: return ResponseEntity(HttpStatus.NOT_FOUND)
return ResponseEntity(event, HttpStatus.OK)
}
@PostMapping("")
fun create(@RequestBody subject: Event): ResponseEntity<Event> {
val created = service.save(subject)
return ResponseEntity(created, HttpStatus.OK)
}
@DeleteMapping("/{id}")
fun delete(@PathVariable id: Long): ResponseEntity<Event> {
service.existsById(id) ?: return ResponseEntity(HttpStatus.NOT_FOUND)
service.delete(id)
return ResponseEntity(HttpStatus.NO_CONTENT)
}
}
Я отправляю запрос на создание нового Event:
{
"name": "test event",
"description": "test event",
"date": "2023-07-22 17:57:42",
"approved": false,
"type": "speak",
"sourceHref": "https://google.com",
"subject": 1
}
На что получаю следующую ошибку:
JSON parse error: Cannot construct instance of `com.example.timestat.models.Subject` (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (1)
Следуя документации, hibernate должен сам подтягивать по id нужный Subject из бд, но он этого не делает, ругаясь на отсутствие конструктора.
Что я делаю не правильно?