Renat Shakerov
Renat Shakerov

Reputation: 3

Patch request for changing ManyToMany association

need some help with REST api for Many-To-Many relationship between Employee and Role using spring data rest

@Entity
@Table(name="employees")
public class Employee  {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="employees_id_seq")
    @SequenceGenerator(name="employees_id_seq", sequenceName="employees_id_seq", allocationSize=1)
    @Column(name="EMPLOYEE_ID")
    private Long id;

    @NotNull
    private String email;

    @ManyToMany(cascade={}, fetch=FetchType.EAGER, targetEntity=Role.class) 
    @JoinTable(
        name="employee_roles",
        joinColumns=@JoinColumn(name="EMPLOYEE_ID", referencedColumnName="EMPLOYEE_ID"),
        inverseJoinColumns = @JoinColumn(name="ROLE_ID", referencedColumnName="ROLE_ID")
    )
    private List<Role> roles;

    public Employee() {
        System.out.println("Employee created");
    }

    public Employee(long id, String firstName, String lastName, String email) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
    }

// Getters , Setter, etc.
}

@Entity
@Table(name="roles")
public class Role {

    @Id
    @Column(name="ROLE_ID")
    private String roleId;
    private String roleName;

    public Role() {

    }
// Getters, Setters, etc
}

Spring Data Repository:

import org.springframework.data.repository.CrudRepository;
public interface EmployeeRepository extends CrudRepository<Employee, Long>{}

Current database status expressed in json received from the rest api:

{
"firstName": "First1",
"lastName": "Last1",
"email": "[email protected]",
"roles": [ {"roleName": "User"}, {"roleName": "Admin"}],
"locationId": 43,
"_links": {
"self": {
"href": "http://localhost:8091/employees/1"
},
"employee": {
"href": "http://localhost:8091/employees/1"
}
}
}

I have the following roles data in the database:

select role_id, role_name from roles

role_id   role_name
-------   -------
adm       Admin
usr       User

I want to remove User role and keep Admin role for the user. I am trying to use PATCH request with the following payload

{
"roles": [ {"roleId": "adm"}]
}

Unfortunately it results in the error:

org.hibernate.HibernateException: identifier of an instance of Role was altered from usr to adm

If I try to remove role Admin with the payload

{ 
  "roles": [ {"roleId": "usr"}] 
}

it works just fine.

It seems the behaviour depends on role Id's order.

Any help or advice is appreciated.

Upvotes: 0

Views: 336

Answers (1)

Alan Hay
Alan Hay

Reputation: 23226

The correct mechanism to alter the collection of roles in SDR would be to send a PATCH request as below:

{ 
  "roles": [ 
      "http://localhost:8091/roles/adm",
      "http://localhost:8091/roles/usr"
  ] 
}

However see the following regression intoduced in Hopper SR5 and due to be fixed in Hooper SR9.

https://jira.spring.io/browse/DATAREST-1041

Upvotes: 0

Related Questions