JPA中使用 @GenericGenerator 自定义方式 生成 主键 ID

一、官网资料

1、文档地址:https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#identifiers-generators-GenericGenerator
2、文档说明:需要实现 org.hibernate.id.IdentifierGenerator 这个接口

1
2
@GenericGenerator allows integration of any Hibernate org.hibernate.id.IdentifierGenerator implementation,
including any of the specific ones discussed here and any custom ones.

3、案例:

二、改造一下官网的案例

1、实体类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@Data
@Entity
@Table(name = OrderTable.TABLE_NAME,
    indexes = {
        @Index(name = "id", columnList = "id", unique = true)
    })
@AllArgsConstructor
@NoArgsConstructor
@Builder
@EntityListeners(AuditingEntityListener.class)
public class OrderTable {

  public static final String TABLE_NAME = "order_table";

  /**
   * 使用 snowflake : 雪花算法。
   */
  @Id
  @GeneratedValue(generator = "couponIdGenerator",
      strategy = GenerationType.SEQUENCE)
  @GenericGenerator(
      name = "couponIdGenerator",
      strategy = "com.wangyk.sharding.config.CouponIdGeneratorConfig"
  )
  private Long id;

  @Column(columnDefinition = "BIGINT(20) COMMENT '订单Id'")
  private Long orderId;

  @Column(columnDefinition = "BIGINT(20) COMMENT '用户Id'")
  private Long userId;

  @Column(columnDefinition = "VARCHAR(255) COMMENT '订单备注'")
  private String remake;

  @Column
  @CreatedDate
  private Date creation;

  @Column
  @LastModifiedDate
  private Date modification;
}

2.实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Slf4j
public class CouponIdGeneratorConfig implements IdentifierGenerator {

  /**
   * Generate a new identifier.
   *
   * @param session The session from which the request originates
   * @param object  the entity or collection (idbag) for which the id is being generated
   * @return a new identifier
   * @throws HibernateException Indicates trouble generating the identifier
   */
  @Override
  public Serializable generate(SharedSessionContractImplementor session, Object object)
      throws HibernateException {
    /**
     * 获取容器中的 Bean
     */
    SnowflakeIdWorker snowflakeIdWorker = SpringUtil.getBean(SnowflakeIdWorker.class);
    long id = snowflakeIdWorker.nextId();
    log.info("id -> [{}]", id);
    return id;
  }
}

3.自定义生成主键ID成功