Reputation: 29
Gone through all the code bit by bit but just can't find what is wrong, if I make postman getUsers request it works fine, but when I make the POST request I get the error:
ERROR 7388 --- [myApiPortifolio] [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.orm.ObjectOptimisticLockingFailureException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.myapps.myApiPortifolio.entities.User#0eb358b8-93d9-4fe1-a457-8a186d0788aa]] with root cause org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect):
It does not create the User to the database, here are my classes:
User Entity
package com.myapps.myApiPortifolio.entities;
import jakarta.persistence.*;
import java.util.List;
import java.util.UUID;
@Entity
@Table(name = "tb_users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private UUID id;
private String username;
private String email;
private String password;
@OneToMany(mappedBy = "user")
private List<Account> accounts;
public User() {
}
public User(UUID id, String username, String email, String password) {
this.id = id;
this.username = username;
this.email = email;
this.password = password;
}
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public List<Account> getAccounts() {
return accounts;
}
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
}
Account Entity
package com.myapps.myApiPortifolio.entities;
import jakarta.persistence.*;
import java.util.UUID;
@Entity
@Table(name = "tb_accounts")
public class Account {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private UUID id;
private String accountType;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
public Account() {
}
public Account(UUID id, String accountType) {
this.id = id;
this.accountType = accountType;
}
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public String getAccountType() {
return accountType;
}
public void setAccountType(String accountType) {
this.accountType = accountType;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
CreateUserDto
package com.myapps.myApiPortifolio.entities.dtos;
public record CreateUserDto(String username, String email, String password) {
}
UserRepository
package com.myapps.myApiPortifolio.repositories;
import com.myapps.myApiPortifolio.entities.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.UUID;
@Repository
public interface UserRepository extends JpaRepository<User, UUID> {
}
UserService
package com.myapps.myApiPortifolio.services;
import com.myapps.myApiPortifolio.entities.User;
import com.myapps.myApiPortifolio.entities.dtos.CreateUserDto;
import com.myapps.myApiPortifolio.repositories.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.UUID;
@Service
public class UserService {
@Autowired
UserRepository userRepository;
public UUID createUser(CreateUserDto createUserDto) {
// DTO -> ENTITY
User user = new User(
UUID.randomUUID(),
createUserDto.username(),
createUserDto.email(),
createUserDto.password()
);
var createdUser = userRepository.save(user);
return createdUser.getId();
}
public List<User> getUsers() {
return userRepository.findAll();
}
}
UserController
package com.myapps.myApiPortifolio.controllers;
import com.myapps.myApiPortifolio.entities.User;
import com.myapps.myApiPortifolio.entities.dtos.CreateUserDto;
import com.myapps.myApiPortifolio.services.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.net.URI;
import java.util.List;
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
UserService userService;
@PostMapping
public ResponseEntity<User> createUser(@RequestBody CreateUserDto createUserDto) {
var userId = userService.createUser(createUserDto);
return ResponseEntity.created(URI.create("/users/" + userId)).build();
}
@GetMapping
public ResponseEntity<List<User>> getUsers() {
var users = userService.getUsers();
return ResponseEntity.ok(users);
}
}
Upvotes: -1
Views: 185
Reputation: 29
I found out that there is nothing wrong with the code in the end, by just removing the UUID id from the User entity Constructor solved the issue, for some reason hibernate tries to create and re-create/overwrite it when the createUser method is invoked requesting a UUID.randomUUID, just by removing it and letting it create by itself just works out, weird though, I had a very similar Api where in the method createUser I had the same structure and worked out normally, don't know, it's running.
Upvotes: 0