Spring Data Jpa автоматически не принимает следующий идентификатор (PK), он всегда начинается с 1

Я разрабатываю пример Spring Boot (2.1.7.RELEASE) +Data Jpa + Postgres. В этом примере я явно передаю EMP_ID value=100, а затем я разрешаю data-jpa автоматически принимать следующий идентификатор, который равен 101. Я не уверен, почему это не работает таким образом ??

Сотрудник.java

@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Entity
public class Employee extends BaseEntity{

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "EMP_ID", unique = true, nullable = false)
    private Integer empId;

    @Column(name = "EMP_NAME", unique = true, nullable = false)
    private String empName;

    @Column(name = "EMP_EMAIL", unique = true, nullable = false)
    private String empEmail;


    @Builder(builderMethodName="eBuilder")
    public Employee(Integer empId, String empName, String empEmail,
            Instant createdDate, Instant lastUpdateDate,String createUser, String lastUpdateUser) {
        super(createdDate, lastUpdateDate, createUser, lastUpdateUser);
        this.empId = empId;
        this.empName = empName;
        this.empEmail = empEmail;
    }
}

BaseEntity.java

@Data
@MappedSuperclass
@NoArgsConstructor
@AllArgsConstructor
@EntityListeners(AuditingEntityListener.class)
public class BaseEntity {
    @CreatedDate
    @Column(name = "createdDate", nullable = false, updatable = false)
    private Instant createdDate;

    @Column(name = "lastUpdateDate", nullable = false)
    @LastModifiedDate
    private Instant lastUpdateDate;

    @Column(name = "createUser", nullable = false, length = 50)
    private String createUser;

    @Column(name = "lastUpdateUser", length = 50)
    private String lastUpdateUser;
}

MainApp.java

@SpringBootApplication
@EnableJpaAuditing
public class MyExampleApplication implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(MyExampleApplication.class, args);
    }

    @Autowired
    private EmployeeRepository employeeRepository;

    @Override
    public void run(String... args) throws Exception {
        Employee e = Employee.eBuilder().empId(100).empName("Shrutika")
                .empEmail("[email protected]")
                .createUser("Shrutika")
                .lastUpdateUser("Shrutika")
                .build();

        employeeRepository.save(e);

        Employee e1 = Employee.eBuilder().empName("Shantaram")
                .empEmail("[email protected]")
                .createUser("Shantaram")
                .lastUpdateUser("Shantaram")
                .build();
        employeeRepository.save(e1);
    }
}

введите здесь описание изображения

Даже если бы я использовал ниже, все равно что-то не работает

@Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "emp_generator")
    @SequenceGenerator(name="emp_generator", sequenceName = "emp_seq", allocationSize=1)
    @Column(name = "EMP_ID", unique = true, nullable = false)
    private Integer empId;

Spring JIRA: https://jira.spring.io/browse/DATAJPA-1588


person Jeff Cook    schedule 11.08.2019    source источник
comment
Возможный дубликат stackoverflow.com/questions/38537463/   -  person asolanki    schedule 12.08.2019
comment
@asolanki - я не согласен с приведенной выше ссылкой, следуя: vladmihalcea.com/. Не могли бы вы предложить правильное руководство?   -  person Jeff Cook    schedule 12.08.2019
comment
@JeffCook генератор последовательности состоит в получении следующего идентификатора из последовательности базы данных. Не в получении следующего идентификатора из идентификатора, который вы в последний раз вставили сами.   -  person JB Nizet    schedule 12.08.2019
comment
@JBNizet - Верно. Соглашаться. Я всегда хотел сохранять записи, всегда делая максимальный идентификатор +1. Есть ли способ сделать это с помощью Spring Data JPA?   -  person Jeff Cook    schedule 12.08.2019
comment
Нет. Это было бы невозможно сделать одновременно безопасным способом, и это было бы ужасно медленно.   -  person JB Nizet    schedule 12.08.2019
comment
В качестве альтернативы я должен сказать initialValue=101, если у меня уже есть 100 в качестве максимального идентификатора, присутствующего в БД? @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="seq") @SequenceGenerator(name="seq", initialValue=99, allocationSize=1)   -  person Jeff Cook    schedule 12.08.2019
comment
Один подход, который я видел, состоит в том, чтобы иметь последовательность для идентификаторов, сгенерированных JPA, и использовать отрицательные идентификаторы для идентификаторов, сгенерированных каким-либо другим процессом. Хотя это, безусловно, квалифицируется как бэдхак в 98% случаев.   -  person Jens Schauder    schedule 19.08.2019
comment
@JensSchauder - мне это непонятно. Не могли бы вы показать код?   -  person Jeff Cook    schedule 19.08.2019


Ответы (3)


Убедитесь, что тип EMP_ID в базе данных: SERIAL или Integer. Для использования IDENTITY с postgres он должен быть SERIAL (https://www.postgresql.org/docs/8.1/datatype.html#DATATYPE-SERIAL).

person sudo    schedule 12.08.2019

Я явно передаю значение EMP_ID = 100, а затем разрешаю data-jpa автоматически принимать следующий идентификатор, равный 101. Я не уверен, почему он не работает таким образом ??

JB Nizet ответил на это в комментариях:

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

Я всегда хотел сохранять записи, всегда делая максимальный идентификатор +1. Есть ли способ сделать это с помощью Spring Data JPA?

И снова Дж. Б. Низе указал на то, что это ужасная идея. Это потребует блокировки индекса или, по крайней мере, индекса для каждой вставки, включая выбор, для определения следующего идентификатора.

Итак: НЕ ДЕЛАЙТЕ ЭТОГО

Если вы все еще хотите это сделать, Влад Михалча описывает, как реализовать собственный генератор идентификаторов. Это должно позволить вам реализовать свой собственный генератор. Конечно, это специфично для Hibernate.

person Jens Schauder    schedule 19.08.2019

Это будет работать:

@GeneratedValue(strategy=GenerationType.SEQUENCE)
person Prashant K    schedule 13.05.2020