适合场景
在使用Spring Data JPA的时候,在使用UUID作为主键的时候,通常都会使用system-uuid
作为主键生成策略,类似配置如下:
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid2")
private String id;
我们都知道,使用save
方法保存实体的时候JAP会根据主键判断是新增(主键为空或者数据库表中无该主键)还是更新(数据库表中有该主键)。
而且,在使用这种如上配置的时候无论实体的主键是否为空,只要在表中不存在,都会再次生成主键,也就是没办法通过给id
属性赋值的形式来自定义实体的id。
而在一些场景下,会有自定义主键的需求,比如主键来源于其他第三方系统,这时候我们期望的还是使用第三方系统的主键作为主键以表示同一条数据,这就需要我们能够实现自定义主键生成策略,并且JPA也提供了这样的通道。
自定义主键生成策略
Spring Data JPA可以通过实现org.hibernate.id.IdentifierGenerator
接口来自定义主键生成器,而同时也提供了许多的内置生成器,就如上文中的system-uuid
生成器,使用uuid2
生成策略实现主键生成,也有实现自增的主键生成器:IncrementGenerator
。
根据需求,可以通过继承org.hibernate.id.UUIDGenerator
生成器来实现自定义ID:
/**
* 自定义UUID生成器
* @author sevenlin
*/
public class CustomUUIDGenerator extends UUIDGenerator {
@Override
public Serializable generate(SessionImplementor session, Object object) throws HibernateException {
Object id = FieldUtil.readField(object, "id");
if (id != null) {
return (Serializable) id;
}
return super.generate(session, object);
}
}
有了自定义主键生成器之后就可以通过如下配置指定该生成器:
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "custom-uuid")
@GenericGenerator(name = "custom-uuid", strategy = "com.sevenlin.dal.CustomUUIDGenerator")
private String id;
这样,就可以实现自定义ID,同时保留原来的主键生成策略不变。