0
votes

I am developing Spring Boot (2.1.7.RELEASE) +Data Jpa + Postgres example. In this example I am explicitly passing EMP_ID value=100 and next I am allowing data-jpa to automatically take next Id which is 101. I am not sure why its not working in that way??

Employee.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);
    }
}

enter image description here

Even if I used below, still things doesn't works well

@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

3
@asolanki - I am not convience with the above link, by following : vladmihalcea.com/…. Could you please suggest proper guidance ? - Jeff Cook
@JeffCook a sequence generator consists in getting the next ID from a database sequence. Not in getting the next ID from the ID you last inserted yourself. - JB Nizet
@JBNizet - Right. Agree. I always wanted to save records by always doing max id +1. Is there any way of doing this with Spring Data JPA? - Jeff Cook
No. This would be impossible to do in a concurrent-safe way, and would be horribly slow. - JB Nizet

3 Answers

0
votes

Ensure the type EMP_ID on the database: SERIAL or Integer. For using IDENTITY with postgres it has to be SERIAL (https://www.postgresql.org/docs/8.1/datatype.html#DATATYPE-SERIAL).

0
votes

I am explicitly passing EMP_ID value=100 and next I am allowing data-jpa to automatically take next Id which is 101. I am not sure why its not working in that way??

JB Nizet answered that in the comments:

a sequence generator consists in getting the next ID from a database sequence. Not in getting the next ID from the ID you last inserted yourself.

I always wanted to save records by always doing max id +1. Is there any way of doing this with Spring Data JPA

Again JB Nizet pointed out this is a terrible idea. It would require a lock on the or at least the index for every insert including the select to determine the next id.

So: DON'T DO THIS

If you still want to do it Vlad Mihalcea describes how to implement a custom id generator. This should allow you to implement your own generator. Of course this is Hibernate specific.

0
votes

This will work:

@GeneratedValue(strategy=GenerationType.SEQUENCE)