jpa使用uuid策略后无法手动设置id
实体对象定义如下:
@data @entity @table(name = "sys_user") public class userdo { /** 用户id */ @id @genericgenerator(name = "uuid", strategy = "org.hibernate.id.uuidgenerator") @generatedvalue(generator = "uuid") @column(length = 36, nullable = false) private string userid; .... }
调用jpa的save方法,即使手动设置了id,手动设置的这个id也会被覆盖。
要求
当用户手动设置了id,以用户设置的id为准,否则使用uuid
解决方案
使用自定义id生成策略,判断id非空
import cn.hutool.core.util.strutil; import lombok.extern.slf4j.slf4j; import org.hibernate.engine.spi.sharedsessioncontractimplementor; import org.hibernate.id.uuidgenerator; import javax.persistence.id; import java.io.serializable; import java.lang.reflect.field; import java.lang.reflect.invocationtargetexception; import java.lang.reflect.method; /** * 自定义uuid生成策略, 扩展 {@link org.hibernate.id.uuidgenerator} * 当用户设置了id,以用户设置的id为主,为空则生成uuid * {@link javax.persistence.id} 注解的字段只处理第一个 * * @author qiudw * @date 7/7/2023 */ @slf4j public class customeruuidgenerator extends uuidgenerator { @override public serializable generate(sharedsessioncontractimplementor session, object obj) { class<?> clazz = obj.getclass(); log.debug("generate id class: {}", clazz.getname()); field[] fields = clazz.getdeclaredfields(); try { for (field field : fields) { id idannotation = field.getannotation(id.class); if (idannotation == null) { continue; } string fieldname = field.getname(); log.debug("field name: {}", fieldname); string getmethodname = generategetmethodname(fieldname); log.debug("get method name: {}", getmethodname); method declaredmethod = clazz.getdeclaredmethod(getmethodname); string idvalue = (string) declaredmethod.invoke(obj); if (strutil.isnotblank(idvalue)) { log.debug("use set value: {}", idvalue); return idvalue; } } } catch (nosuchmethodexception e) { log.error("no such method", e); } catch (invocationtargetexception | illegalaccessexception e) { log.error("invoke exception", e); } return super.generate(session, obj); } /** * 生成get和set的方法名称 * type + 首字母大写(fieldname) * * @param fieldname userid * @return type = set, fieldname = userid, 返回 setuserid */ private string generategetmethodname(string fieldname) { return "get" + fieldname.substring(0, 1).touppercase() + fieldname.substring(1); } }
实体对象使用自定的策略
@data @entity @table(name = "sys_user") public class userdo { /** 用户id */ @id @genericgenerator(name = "uuid", strategy = "com.user.customeruuidgenerator") @generatedvalue(generator = "uuid") @column(length = 36, nullable = false) private string userid; .... }
现在可以手动设置id了
不设置则自动生成uuid
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论