当使用Spring Data JPA和Mysql作为持久层框架和数据库时,通常用@Id和@GeneratedValue来指定一个自增的主键,这时,Data JPA就会自动根据数据库和你传入的内容来判断你要持久化的实体是进行新建操作还是修改操作。
但是上面这种做法会带来一个弊端,就是当我们想要对数据库插入指定ID的实体时,Data JPA还是会忽略你Entity中的id信息,而选择继续自增插入。
这时,就需要自定义一个主键的生成策略,指定当Entity包含id信息并且与数据库中现有的id不冲突时,按指定id执行插入操作,具体方法如下:
在Entity的ID字段上加注解
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY, generator = "UserIdentityGenerator")
@GenericGenerator(name = "UserIdentityGenerator", strategy = "com.demo.UserIdentityGenerator")
private Long id;
复制代码
其中com.demo.UserIdentityGenerator是自定义的生成策略,其内容如下:
package com.demo;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.id.IncrementGenerator;
import java.io.Serializable;
public class UserIdentityGenerator extends IncrementGenerator {
@Override
public Serializable generate(SessionImplementor sessionImplementor, Object object) throws HibernateException {
Serializable id = sessionImplementor.getEntityPersister(null, object)
.getClassMetadata().getIdentifier(object, sessionImplementor);
return id != null ? id : super.generate(sessionImplementor, object);
}
}
复制代码
但是这个方法由于继承了IncrementGenerator,所以也同样会在多个实例的情况下出现主键重复的情况,不建议在多服务环境下使用。