Spring Boot JPA实体构造时无法自动生成自定义ID的求助
问题原因与解决方案
核心原因
Hibernate的@GeneratedValue自定义生成器不会在你用new创建实体实例时触发,它的执行时机是在实体被持久化(即调用save()/persist()方法写入数据库)的阶段,此时Hibernate才会调用生成器生成ID并赋值到实体的对应字段上。
解决方案
方案1:持久化后获取ID
如果不需要在保存到数据库前拿到ID,只需在调用Repository的save()方法后,再调用myEntity.getTransactionNumber()即可获取生成的ID:
TransactionsEntity myEntity = new TransactionsEntity(); // 设置其他字段 myEntity = transactionRepository.save(myEntity); String generatedId = myEntity.getTransactionNumber(); // 此时能拿到ID
方案2:手动生成ID(持久化前获取)
如果需要在实例化时就拿到ID,可以把生成逻辑从SequenceGenerator中抽离为公共方法,手动调用赋值:
- 修改生成器代码,抽出生成逻辑:
public class SequenceGenerator implements IdentifierGenerator { public static final String generatorName = "6CharGenerator"; // 抽离公共静态方法用于手动生成 public static String generateTransactionId() { return RandomGenerator.GenerateRandomStringUpperCaseOnlyNoSimilarChars(6); } @Override public Serializable generate(SharedSessionContractImplementor session, Object entity) throws HibernateException { return generateTransactionId(); } }
- 实例化实体时手动赋值:
// 无参构造方式 TransactionsEntity myEntity = new TransactionsEntity(); myEntity.setTransactionNumber(SequenceGenerator.generateTransactionId()); // Builder模式(推荐,因为你加了@Builder注解) TransactionsEntity myEntity = TransactionsEntity.builder() .transactionNumber(SequenceGenerator.generateTransactionId()) .build();
方案3:调整实体注解
你的实体中transactionNumber字段加了@NonNull注解,这会导致无参构造实例化时该字段为null,可能触发校验异常。如果要依赖Hibernate自动生成ID,建议去掉@NonNull注解,因为持久化前该字段确实为null,Hibernate会在持久化时自动赋值。
内容的提问来源于stack exchange,提问作者Jason Chan
相关产品推荐
相关产品推荐

