我正在重构系统以使用Spring Boot / JPA / Hibernate。 有一个例程,其中客户端实例从中央服务器接收要保存的对象列表。列表中的每个对象都有一个由中央服务器生成的ID,在客户端实例上插入时,我必须使用相同的ID,但是我实体上的此ID是一个“自动增量”字段。
我的实体:
@Entity
@Table(name = "usuario", schema = "adm")
@SequenceGenerator(name="seq_usuario_generator", sequenceName = "adm.seq_usuario", allocationSize=1)
public class UsuarioEntity implements java.io.Serializable {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_usuario_generator")
@Column(name = "id_usuario", unique = true, nullable = false)
private int id;
@Column(name = "name", length = 50)
private String name;
@Column(name = "active")
private Boolean active;
// getter and setter ommited
....
}
应该有这样的东西:
...
UsuarioEntity user = new UsuarioEntity();
user.setId(idFromCentralServer);
user.setName("Testing insert with given ID");
usuarioRepo.save(user);
...
执行此代码时,给定的ID被忽略,并从本地序列中生成一个新的ID。
有什么方法可以保存一个可以设置ID的对象,而无需从序列中获取它?
答案 0 :(得分:0)
只需删除@GeneratedValue
批注
@Id
@Column(name = "id_usuario", unique = true, nullable = false)
private int id;
答案 1 :(得分:0)
也许这不是我能得到的最优雅的解决方案,但它现在解决了我的问题。
我创建了一个自定义序列生成器,如下所示:
public class CustomSequenceGenerator extends SequenceStyleGenerator implements Configurable {
private String sequenceCallSyntax;
@Override
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
sequenceCallSyntax = "SELECT nextval('" + params.getProperty("sequence_name") + "')";
super.configure(type, params, serviceRegistry);
}
@Override
public Serializable generate(SessionImplementor s, Object obj) {
Serializable id = s.getEntityPersister(null, obj).getClassMetadata().getIdentifier(obj, s);
if (id != null && Integer.valueOf(id.toString()) > 0) {
return id;
} else {
Integer seqValue = ((Number) Session.class.cast(s)
.createSQLQuery(sequenceCallSyntax)
.uniqueResult()).intValue();
return seqValue;
}
}
}
我的实体是这样的:
@Entity
@Table(name = "usuario", schema = "adm")
@GenericGenerator(name = "CustomSequenceGenerator",
strategy = "<....my_package...>.CustomSequenceGenerator",
parameters = {
@Parameter(name = "sequence_name", value = "adm.seq_usuario")
})
public class UsuarioEntity implements java.io.Serializable {
@Id
@GeneratedValue(generator = "CustomSequenceGenerator", strategy = GenerationType.SEQUENCE)
@Column(name = "id_usuario", unique = true, nullable = false)
private int id;
@Column(name = "name", length = 50)
private String name;
@Column(name = "active")
private Boolean active;
// getter and setter ommited
....
}
这样,当我在服务上保存ID为null的实体时,生成器会从我的序列中返回nextval,并且如果我设置了中央服务器提供的ID,它将被正确插入表中。 / p>
如果有更好的解决方案,请让我知道以更新此答案。