前提
@GeneratedValue(strategy = GenerationType.UUID) 默认会覆盖自己设定的值,导致自己主动设置的字段被重新覆盖
方案一 @PrePersist 声明周期内修改方式。
@PrePersist
protected void onCreate() {
if (this.id == null) {
this.id = Objects.requireNonNullElseGet(this.objectId, () -> IdUtil.fastUUID().toLowerCase(Locale.ROOT));
}
}
方案二 自定义字段生成规则
当前代码仅适用于 Hibernate 6 以上,新版本中已经弃用了
UUIDGenerator之类的实现需要采用新的实现。
OverflowUUIDGenerator.java
import cn.hutool.core.util.IdUtil;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.generator.BeforeExecutionGenerator;
import org.hibernate.generator.EventType;
import org.hibernate.id.IdentityGenerator;
import java.util.Objects;
public class OverflowUUIDGenerator extends IdentityGenerator implements BeforeExecutionGenerator {
private static Object getId(Object entity, SharedSessionContractImplementor session) {
return session.getEntityPersister(null, entity).getIdentifier(entity, session);
}
@Override
public Object generate(SharedSessionContractImplementor session, Object entity, Object currentValue,
EventType eventType) {
// 尝试获取现有的 ID
Object id = getId(entity, session);
// 如果 ID 为空,则生成一个新的 UUID
if (Objects.isNull(id)) {
id = IdUtil.randomUUID().toLowerCase();
// 设置生成的 ID 回到实体中
session.getEntityPersister(null, entity).setIdentifier(entity, id, session);
}
return id;
}
@Override
public boolean generatedOnExecution(Object entity, SharedSessionContractImplementor session) {
Object id = getId(entity, session);
return Objects.isNull(id) || id instanceof String && ((String) id).isEmpty();
}
@Override
public boolean generatedOnExecution() {
return true;
}
}
ColumnOverflowUUIDGenerator.java
import org.hibernate.annotations.IdGeneratorType;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.FIELD })
@IdGeneratorType(OverflowUUIDGenerator.class)
public @interface ColumnOverflowUUIDGenerator {
}
使用方式
@Id
@ColumnOverflowUUIDGenerator
@Column(name = "id", nullable = false)
private String id;