JPA Hibernate - вставка с заданным идентификатором, а не с последовательностью - PullRequest
1 голос
/ 20 марта 2019

Я реорганизую систему для использования Spring Boot / JPA / Hibernate.Существует процедура, когда экземпляры клиентов получают список объектов от центрального сервера для сохранения.Каждый объект из списка имеет идентификатор, сгенерированный центральным сервером, и я должен использовать тот же идентификатор при вставке на экземпляры моих клиентов, но этот идентификатор на моем объекте является полем автоинкремента.

Мой объект:

@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);
...

Когда я выполняю этот код, данный идентификатор игнорируется, а новый генерируется из локальной последовательности.

Есть ли способ сохранить объект, где я могу установить идентификатор, не получая его из моей последовательности?

Ответы [ 2 ]

0 голосов
/ 21 марта 2019

Возможно, это не самое элегантное решение, которое я мог бы в итоге найти, но оно решило мою проблему на данный момент.

Я создал генератор пользовательских последовательностей следующим образом:

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
    ....
}

Таким образом, когда я сохраняю сущность с идентификатором NULL в моем сервисе, генератор возвращает nextval из моей последовательности, и если я устанавливаю идентификатор, который был задан центральным сервером, он корректно вставляется в мою таблицу.

Если есть более элегантное решение, пожалуйста, дайте мне знать, чтобы обновить этот ответ.

0 голосов
/ 20 марта 2019

Просто удалите аннотацию @GeneratedValue

 @Id
 @Column(name = "id_usuario", unique = true, nullable = false)
 private int id;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...