解决Kotlin下使用@Transactional等Spring代理类空指针异常

直接上代码

1
2
3
4
5
6
7
8
9
10
11
open class BaseController<T : BaseEntity>(val baseService: BaseService<T>) {

@Transactional
@AuthRequired
@PatchMapping("/{id}")
open fun updateById(@PathVariable("id") id: Long, @RequestBody entity: T): ResponseEntity<T> {
entity.id = id
return ResponseEntity.ok(baseService.updateById(entity))
}

}

访问controller时出现NullPointerException,此时baseService为null

原因解析

Kotlin的字段和方法一样默认都是final,即无法被子类重写,所以意味着被编译为字节码后字段的getter和setter都是final的,无法被代理类重写,在调用时当然就会出现空指针

解决方案

为baseService添加修饰符open,即

1
2
3
4
5
6
7
8
9
10
11
open class BaseController<T : BaseEntity>(open val baseService: BaseService<T>) {

@Transactional
@AuthRequired
@PatchMapping("/{id}")
open fun updateById(@PathVariable("id") id: Long, @RequestBody entity: T): ResponseEntity<T> {
entity.id = id
return ResponseEntity.ok(baseService.updateById(entity))
}

}

事实上启用了kotlin-spring插件后,被@Component等注解修饰的类成员会自动为open状态,但是由于上述类为父类,未被注解修饰才发生这种情况

解决Kotlin下使用@Transactional等Spring代理类空指针异常

https://jktu.cc/解决Kotlin下使用@Transactional等Spring代理类空指针异常/

作者

udp_bbr

发布于

2021-07-18

更新于

2021-07-19

许可协议