用例是在保存新实体时,IdentityColumn 有两个选项
如果 id 列为空,则生成 auto_increment id(与
@GeneratedValue(strategy = GenerationType.IDENTITY)
完美配合)
如果 id 列不为空,则不生成自动递增 id,并使用我们在保存实体时手动设置的相同 id。通过在身份列上使用下面的注释,将 Hibernate 分配的生成器与身份生成器的组合也可以正常工作。
@Id
@org.springframework.data.annotation.Id
@GeneratedValue(strategy = GenerationType.IDENTITY, generator = "CustomIdGenerator")
@GenericGenerator(name = "CustomIdGenerator", strategy = "com.CustomIdentityGenerator ")
private Long id;
这两个用例都可以在 hibernate 版本 5.X 上正常工作,并使用以下“CustomIdentityGenerator”代码
public class CustomIdentityGenerator extends IdentityGenerator {
@Override
public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException {
Serializable id = session.getEntityPersister(null, object).getClassMetadata().getIdentifier(object, session);
return id != null && id != Integer.valueOf(0) ? id : super.generate(session, object);
}
}
但是,更新到 hibernate 版本 6.X 后,'IdentityGenerator' 中不存在生成方法。尝试了多种方法来覆盖但没有任何效果。
在 hibernate 6.X 中是否有可能实现这个用例?
我在使用 Hibernate 6.2.5 Final 时遇到了同样的问题,在探索中我发现了
IdentifierGenerator
接口,它有 generate
方法,通过在你的类中实现 IdentifierGenerator
CustomIdentityGenerator
你可以实现你所需要的,
public class CustomIdentityGenerator implements IdentifierGenerator {
@Override
public Serializable generate(SharedSessionContractImplementor session, Object object) {
\\ your logic
}
}
这是我的完整课程,其中包含逻辑,以防有人需要。
import java.io.Serializable;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.persister.entity.EntityPersister;
public class NativeIfNotAssignedIdentityGenerator implements IdentifierGenerator {
private static final long serialVersionUID = 1L;
@Override
public Serializable generate(SharedSessionContractImplementor session, Object entity)
throws HibernateException {
final Random r = new Random();
final Set<Integer> s = new HashSet<>();
for(int i = 0; i < 4; i++){
while(true) {
int num = r.nextInt(4) + 1;
if (s.contains(num) == false) {
s.add(num);
break;
}
}
}
Serializable idOld;
Serializable idNew = "";
EntityPersister persister = session.getEntityPersister(null, entity);
// Determine if an ID has been assigned.
idOld = (Serializable) persister.getIdentifier(entity, session);
if (idOld == null) {
idNew = (Serializable) s;
}
return idNew;
}
}
不幸的是,在 hibernate 6.2+ 中不再允许混合执行前/后 ID 生成器,请参阅 hibernate bug