我在Sping Boot 应用程序中有一个实体类,我已经为ID字段实现了一个自定义ID生成器。然而,使用默认构造函数构造实体时不会生成ID。我需要在创建实体的新示例时自动生成ID,如下所示:TransactionsEntity myEntity = new TransactionsEntity();
然后调用myEntity.getId()
来检索生成的ID。
下面是我的Entity类:
@Entity
@Table(name = "transactions")
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public class TransactionsEntity {
@Id
@NonNull
@Column(name = "transactionNumber", columnDefinition = "varchar(18)", length = 18)
@GeneratedValue(generator = SequenceGenerator.generatorName)
@GenericGenerator(name = SequenceGenerator.generatorName, strategy = "com.vendify.Dependencies.Tools.Spring.Generators.SequenceGenerator")
private String transactionNumber;
}
字符串
这是我的Generator:
public class SequenceGenerator implements IdentifierGenerator {
public static final String generatorName = "6CharGenerator";
@Override
public Serializable generate(SharedSessionContractImplementor sharedSessionContractImplementor, Object o) throws HibernateException {
return RandomGenerator.GenerateRandomStringUpperCaseOnlyNoSimilarChars(6);
}
}
型
尽管如此,构造函数并没有按照预期生成一个ID。我将非常感谢任何指导或帮助解决这个问题!
1条答案
按热度按时间biswetbf1#
当你通过构造函数创建实体时,Jpa并不知道它的任何信息。当你调用p
EntityManager.persist()
时,它会知道你的新实体。这是您的实体成为“托管”并获得分配的键的时刻。键生成策略确定数据库中的记录是立即创建还是稍后创建(在事务提交之前的某个时间,请参阅刷新策略)。
如果使用策略
@GeneratedValue(strategy = GenerationType.IDENTITY)
,则使用生成的数据库主键,因此需要立即INSERT
。如果使用序列或自定义策略,则不需要数据库操作来生成键,因此插入可以推迟到稍后的时间点,这可以带来很大的性能优势。底线:仅仅调用实体的构造函数不会触发JPA。如果你想在调用
EntityManager.persist()
之前分配transactionNumber
,你必须在构造函数中完成。然而,由于它被标记为@Id,这可能会触发unexpexted结果,因为IdentyManager认为实体已经持久化(因为它有一个持久化的Id),但我不太确定。