melodic_n
melodic_n

Reputation: 47

Error modifying an entity in springboot : Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) :

In my spring boot application, I have an employe entity and a user entity , that are practically the same , just user has email and password so this entity is used only for authentication but this user references a specific employe so in database table user (id,email,password,employe_id) and employe(id,fname,lname,email,password,....,user_id) , and employe can be a manager or HR or just a simple employe so those are the role(id,role_name) and to associate each user with a role there is a join table user_role(user_id,role_id) , so this is my database structure now I am having issues when modifying information of an employee , changing the other fields goes normal but when it comes to changing role,which requires to delete a user then create a user with a different role then associate it with the modified employe : this is the method that returns that error

 @Transactional
   public void modifyEmployee(Long id, String nom, String prenom, 
  String email, String  motdepass
         Departement departement, Long solde, String role) throws 
     EmployeExistException {
         Employe employe = emp.findById(id)
         .orElseThrow(() -> new NoSuchElementException("Employee not 
  found with ID: " + id));

         // Update employee details
         if (nom != null) employe.setNom(nom);
         if (prenom != null) employe.setPrenom(prenom);
         if (email != null) employe.setEmail(email);
         if (motdepass != null) employe.setMotdepass(motdepass);
         if (departement != null) employe.setDepartement(departement);
         if (solde != null) employe.setSoldeconge(solde);

         // Check if a role change is requested
         if (role != null) {
             User oldUser = employe.getUser();
             if (oldUser != null) {
                 userRepository.delete(oldUser);

                 System.out.println("Deleted old user");
             }

             // Create a new user with the specified role
             User newUser = createUserWithRole(employe, role);
             employe.setUser(newUser);
             System.out.println("Created new user with role: " + role);
         }

         // Save the modified employee
         emp.save(employe);
     }

User :

 @Table(name = "users", 
  uniqueConstraints = { 
    @UniqueConstraint(columnNames = "username"),
    @UniqueConstraint(columnNames = "email") 
})
  public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@NotBlank
@Size(max = 50)
@Email
 private String email;

 @NotBlank
 @Size(max = 120)
 private String password;

@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(  name = "user_roles", 
    joinColumns = @JoinColumn(name = "user_id"), 
    inverseJoinColumns = @JoinColumn(name = "role_id"))

 private Set<Role> roles = new HashSet<>();
 @OneToOne(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
 private Employe employe;

Employe :

public class Employe {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    protected Long id;
    protected String nom;
    protected String prenom;
    protected String email;
    protected String motdepass;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "departement")
    protected Departement departement;
    protected Long soldeconge;
    @OneToMany(mappedBy = "emp", cascade = CascadeType.ALL)
    protected List<Demande> demandes;
    @OneToMany(mappedBy = "emp", cascade = CascadeType.ALL)
    protected List<Conge> conges;
    protected LocalDate created_at;
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    private User user;

Upvotes: 0

Views: 92

Answers (1)

Chip01
Chip01

Reputation: 11

@Transactional
public void modifyEmployee(Long id, String nom, String prenom, String email, String motdepass, Departement departement, Long solde, String role) throws EmployeExistException {
    Employe employe = emp.findById(id)
            .orElseThrow(() -> new NoSuchElementException("Employee not found with ID: " + id));

    // Update employee details
    if (nom != null) employe.setNom(nom);
    if (prenom != null) employe.setPrenom(prenom);
    if (email != null) employe.setEmail(email);
    if (motdepass != null) employe.setMotdepass(motdepass);
    if (departement != null) employe.setDepartement(departement);
    if (solde != null) employe.setSoldeconge(solde);

    // Check if a role change is requested
    if (role != null) {
        User oldUser = employe.getUser();
        if (oldUser != null) {
            // Remove the association with the old user
            employe.setUser(null);
            userRepository.delete(oldUser);
            System.out.println("Deleted old user");
        }

        // Create a new user with the specified role
        User newUser = createUserWithRole(employe, role);
        employe.setUser(newUser);
        System.out.println("Created new user with role: " + role);
    }

    // Save the modified employee
    emp.save(employe);
}

private User createUserWithRole(Employe employe, String role) {
    User user = new User();
    user.setEmail(employe.getEmail()); // Set email from employe
    user.setPassword(employe.getMotdepass()); // Set password from employe

    // Find the role by name
    Role userRole = roleRepository.findByRoleName(role)
            .orElseThrow(() -> new NoSuchElementException("Role not found: " + role));

    user.getRoles().add(userRole);
    user.setEmploye(employe);

    return userRepository.save(user);
}

In this updated version of the modifyEmployee method, we first remove the association between the old user and the employe before deleting the old user. Then, we create a new user with the specified role and associate it with the employe. Finally, we save the modified employe. Make sure to adjust the createUserWithRole method according to your actual implementation of creating a user with a specified role. This approach ensures that the role change process is handled correctly without causing any issues with the database relationships.
I have not tried this out yet, and I am a newbie, so correct me if I'm wrong!

Upvotes: 0

Related Questions