DMITRY.
03/30/2021, 11:21 AMmongoOperations.findAndModify(searchQuery, update, T::class.java)
Cannot use 'T' as reified type parameter. Use a class instead.
How make it work?Roukanken
03/30/2021, 11:56 AMKClass<T>
as parameter to it too, and use that instead of T::class
DMITRY.
03/30/2021, 11:58 AM@PatchMapping(value = ["{taskId}"], consumes = ["application/json"])
fun updateTask(@PathVariable("taskId") taskId: ObjectId, @RequestBody task: T, taskClass: KClass<T>): ResponseEntity<Void> {
val document = Document()
mongoOperations.converter.write(task, document)
val update = Update()
document.forEach { key: String, value: Any -> update[key] = value }
mongoOperations.findAndModify(Query(Criteria("_id").`is`(taskId)), update, taskClass.java)
return ResponseEntity<Void>(HttpStatus.NO_CONTENT)
}
DMITRY.
03/30/2021, 11:58 AMjava.lang.ClassCastException: class jdk.proxy3.$Proxy99 cannot be cast to class kotlin.jvm.internal.ClassBasedDeclarationContainer (jdk.proxy3.$Proxy99 is in module jdk.proxy3 of loader org.springframework.boot.devtools.restart.classloader.RestartClassLoader @2a01e51d; kotlin.jvm.internal.ClassBasedDeclarationContainer is in unnamed module of loader 'app')
Roukanken
03/30/2021, 12:02 PMtaskClass
argument properly, will it...
won't it just pass null there?DMITRY.
03/30/2021, 12:04 PMprintln(taskClass)
{}
Roukanken
03/30/2021, 12:05 PMT
is generics of the class containing this
how exactly are you using this? Since no idea wth Spring does with generic controllers...
is it just some base controller that you are extending from others?Roukanken
03/30/2021, 12:08 PMclass GenericController<T>
and then you have classes like class AbcController : GenericController<Abc>()
?DMITRY.
03/30/2021, 12:17 PMabstract class Task(
val id: ObjectId?,
var deadline: java.time.LocalDateTime?,
)
Then classes like this
class Change(
id: ObjectId?,
deadline: LocalDateTime?,
worker: ObjectId?,
) : Task(id, deadline)
Interface:
interface TaskController<T: Any> {
val mongoOperations: MongoOperations
@PatchMapping(value = ["{taskId}"], consumes = ["application/json"])
fun updateTask(@PathVariable("taskId") taskId: ObjectId, @RequestBody task: T, taskClass: KClass<T>): ResponseEntity<Void> {
...
mongoOperations.findAndModify(Query(Criteria("_id").`is`(taskId)), update, taskClass.java)
...
}
}
And then controller:
@RestController
@RequestMapping("change")
class ChangeController(
override val taskRepository: ChangeRepository,
override val mongoOperations: MongoOperations,
) : TaskController<Change>
DMITRY.
03/30/2021, 12:18 PMmongoOperations.findAndModify(Query(Criteria("_id").`is`(taskId)), update, Change::class.java)
Roukanken
03/30/2021, 12:23 PMabstract class TaskController<T: Any> (
private val taskClass: KClass<T>
) {
// ...
}
then use it like this from the controllers that extend it:
class ChangeController : TaskController<Change> (Change::class) {
}
tiny bit of repeating yourself, but it would definitely workRoukanken
03/30/2021, 12:27 PMinterface TaskController<T: Any> {
val taskClass: KClass<T>
}
class ChangeController : TaskController<Change> {
override val taskClass = Change::class
}
tho I think it's definitelly an abstract class in spirit, even in your code now, not just an interfaceDMITRY.
03/30/2021, 12:30 PMDMITRY.
03/30/2021, 12:30 PMRoukanken
03/30/2021, 12:41 PM