1

After first starting the api, the first 3 user creation Post requests fail (screenshot at bottom of post) with the below error (unique constraint vilocation).

Subsequent requests work, with the first created user having an id of 4, then 5, etc...

How can I make the user creation work on the first (3) tries?

I suspect this relates to the pre-seeding of my users, which I'm doing with the below script. Possibly the auto ID generation first tries 1,2,3 -- which are already in use?

INSERT INTO user VALUES (1, 'user1', 'pass1', 'ADMIN'); INSERT INTO user VALUES (2, 'user2', 'pass2', 'USER'); INSERT INTO user VALUES (3, 'user3', 'pass3', 'ADMIN')

could not execute statement; SQL [n/a]; constraint [\"PRIMARY KEY ON PUBLIC.USER(ID)\"; SQL statement:\ninsert into user (name, password, role, id) values (?, ?, ?, ?) [23505-196]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement",

@RestController
public class UserResource {

    @Autowired
    private UserRepository userRepository;

    @GetMapping("/users")
    public List<User> retrievaAllUsers() {
        return userRepository.findAll();
    }

    @DeleteMapping("/users/{id}")
    public void deleteUser(@PathVariable Long id) {
        userRepository.deleteById(id);
    }

    @PostMapping("/users")
    public ResponseEntity<Object> createUser(@RequestBody User user) {
        User savedUser = userRepository.save(user);

        URI location = ServletUriComponentsBuilder.fromCurrentRequest()
                .path("/{id}")
                .buildAndExpand(savedUser.getId())
                .toUri();

        return ResponseEntity.created(location).build();

    }


}

-

@Entity
@Table(name = "user")
public class User {

    @Id
    @GeneratedValue
    private Long id;
    private String name;
    private String password;
    @Enumerated(EnumType.STRING)
    private Role role;

    public User() {
        super();
    }

    public User(Long id, String name, String password, Role role) {
        this.id = id;
        this.name = name;
        this.password = password;
        this.role = role;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Role getRole() {
        return role;
    }

    public void setRole(Role role) {
        this.role = role;
    }
}

enter image description here

  • edit - added role class

    public enum Role {
    
    USER, ADMIN
    

    }

12
  • what is the structure of Role class ? Commented Sep 21, 2018 at 20:17
  • @benjaminc edited to include source Commented Sep 21, 2018 at 20:19
  • does it work if there's not data in table ? Commented Sep 21, 2018 at 20:23
  • 1
    default strategy is GenerationType.AUTO @benjaminc . Both same. Commented Sep 21, 2018 at 20:32
  • 1
    If you are using AUTO_INCREMENT in the column definition, then try changing strategy from GenerationType.Auto to GenerationType.Identity Commented Sep 21, 2018 at 20:37

3 Answers 3

1

If you are using AUTO_INCREMENT in the column definition, then try changing strategy from GenerationType.AUTO to GenerationType.IDENTITY.

I noticed a similar behavior when I upgraded a project from Spring Boot 1.5 to 2.0.

Sign up to request clarification or add additional context in comments.

Comments

1

Just an assumption. Firstly you are insterting datas with sql , but in your code you are creating new user and saving to db. So this new creation gives id as 1. But your db has a user record which primary key is as 1. Please remove all values from db and create your records from rest controller.

In my opinion, use a sequnce like this ,dont forget to create sequence in db;

@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_generator")
@SequenceGenerator(name="user_generator", sequenceName = "user_seq", allocationSize=50)

Or read this and choose for your problem to solve.

  • AUTO: Hibernate selects the generation strategy based on the used dialect,
  • IDENTITY: Hibernate relies on an auto-incremented database column to generate the primary key,
  • SEQUENCE: Hibernate requests the primary key value from a database sequence,
  • TABLE: Hibernate uses a database table to simulate a sequence.

PS: Identity should be more relevant but try others.

Comments

1

you should provide the column names also to make sure it's ordered.

INSERT INTO user (id, name, password, role) VALUES (1, 'user1', 'pass1', 'ADMIN');

INSERT INTO user (id, name, password, role) VALUES (2, 'user2', 'pass2', 'USER');

INSERT INTO user (id, name, password, role) VALUES (3, 'user3', 'pass3', 'ADMIN')

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.