JPA Hibernate-插入具有给定ID而不是序列的

时间:2019-03-20 04:37:36

标签: java hibernate spring-boot spring-data-jpa spring-data

我正在重构系统以使用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的对象,而无需从序列中获取它?

2 个答案:

答案 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>

如果有更好的解决方案,请让我知道以更新此答案。