Przy próbie zapisu encji z referencją do innej już istniejącej dostaje błąd "duplicate entry for key".
Wygląda to tak jakby entityManager chciał zapisać dodane do klasy Employee objekty UserPermission jeszcze raz w bazie danych zamiast po prostu ustanowić relację.
Jak można to naprawić?
@Entity
@Table(name = "employee")
public class Employee implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer employee_id;
@Column(unique = true)
private String username;
private String password;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
private List<UserPermission> userPermissions;
private String name;
private String surname;
private String position;
private String phoneNumber;
private Boolean enabled;
public Employee() {
}
public Employee(String username, String password, List<UserPermission> userPermissions, String name, String surname, String position, String phoneNumber) {
this.username = username;
this.password = password;
this.userPermissions = userPermissions;
this.name = name;
this.surname = surname;
this.position = position;
this.phoneNumber = phoneNumber;
this.enabled = true;
}
}
// getters && setters
@Entity
@Table(name = "permission")
public class UserPermission implements GrantedAuthority {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "permission")
private String permission;
public UserPermission() {
}
public UserPermission(String permission) {
this.permission = Permission.valueOf(permission).getRoleName();
}
public void setAuthority(String permission) {
this.permission = permission;
}
@Override
public String getAuthority() {
return permission;
}
}
public void createNewUser(CreateUserRequest createUserRequest) {
Employee employee = employeeWrapper.employeeRequestToEmployee(createUserRequest);
employee.setPassword(passwordEncoder.encode(employee.getPassword()));
try {
employeeRepository.addUser(employee);
} catch (Exception e) {
System.out.println("exception " + e.getMessage() + " " + e.getCause());
}
}
public Employee employeeRequestToEmployee(CreateUserRequest createUserRequest) {
List<UserPermission> allPermisions = userPermissionRepository.getAllPermisions();
List<UserPermission> allMatchingPermissions = allPermisions.stream()
.filter(ap -> createUserRequest.getUserPermissions().contains(ap.getAuthority()))
.collect(Collectors.toList());
Employee employee = new Employee(createUserRequest.getUsername(),
createUserRequest.getPassword(),
allMatchingPermissions,
createUserRequest.getName(),
createUserRequest.getSurname(),
createUserRequest.getPosition(),
createUserRequest.getPhoneNumber());
return employee;
}
@Transactional
public void addUser(Employee user) {
entityManager.persist(user);
}
@Transactional
public List getAllPermisions() {
return entityManager.createQuery("SELECT p FROM UserPermission p")
.getResultList();
}