Kotlin实体使用JPA的save自动设置id问题
背景
最近打算把公司后端项目从Java迁移到Kotlin,在迁移JPA实体类的时候,用data class代替了Java定义的class,同时用var+默认值的方式改写了id的定义
1 | data class User( |
改完后上线发现jpaRepository.save方法不会对实体参数自动设置id了,于是便开始debug
探寻
跟踪jpaRepository.save
1 |
|
发现有个isNew的判断,继续跟踪isNew
1 | public boolean isNew(T entity) { |
默认实现是通过id类型判断,如果是number类型,判断是否为0,否则判断是否为null。
看到这思路已经出来大半了,上面data class定义的id类型是String,由于Kotlin语法要求,非空类型 设置了默认值,于是isNew先进入了第一个if,然后返回false,那么save方法就进入了merge的分支。
而Java版本没有设置默认值,所以默认为null,isNew返回true,区别就在这里。由于传入的实体已经存在id(虽然没有值)于是merge操作便不会给传入的实体赋值生成的id。
解决
问题都查清楚了,那要怎么解决这个问题呢
- 使用number类型作为主键
- 使用Kotlin可空类型作为主键
- 不要依赖参数自动设置,强制使用返回值作为后续使用的实体