如何在hibernate 6.X中仅当身份列为空时在hibernate中生成自动递增id?

问题描述 投票:0回答:3

用例是在保存新实体时,IdentityColumn 有两个选项

  1. 如果 id 列为空,则生成 auto_increment id(与

    @GeneratedValue(strategy = GenerationType.IDENTITY)

    完美配合)
  2. 如果 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 中是否有可能实现这个用例?

java hibernate entity-framework-6
3个回答
0
投票

我在使用 Hibernate 6.2.5 Final 时遇到了同样的问题,在探索中我发现了

IdentifierGenerator
接口,它有
generate
方法,通过在你的类中实现
IdentifierGenerator
CustomIdentityGenerator
你可以实现你所需要的,

public class CustomIdentityGenerator implements IdentifierGenerator {

    @Override
    public Serializable generate(SharedSessionContractImplementor session, Object object) {
    
    \\ your logic
    
    }

}

0
投票

这是我的完整课程,其中包含逻辑,以防有人需要。

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;
  }
}

0
投票

不幸的是,在 hibernate 6.2+ 中不再允许混合执行前/后 ID 生成器,请参阅 hibernate bug

© www.soinside.com 2019 - 2024. All rights reserved.