0

I have struggled to get a good way to relate a Role entity to my User entity in Java Hibernate. I have a User entity which has a List of Role entities. I want to relate them so if a User is deleted all the Role entities which have that User are also deleted with a cascade or the like.

I started off with a @OneToMany (User) & ManyToOne (Role) relationship between the two entities, but when I delete the User it just set the column which contained the user in the role table to NULL. It was then suggested the relationship was @ManyToMany however this caused Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements which I have yet to successfully resolve. Hence I ask what is the best way to achieve the desired relationship between the User and Role before i go too far down the rabbit hole.

Please note: In this example the Role is more of a permission, so users can have the same permission but they are linked to the username. In the table below you can see digby.tyson has the same role as reed.robert no. 7, but if digby was deleted then the role on reed should remain

User.java

@SerializedName("userrole")
@Expose
// @OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
private List<Role>   userRoles = new ArrayList<Role>();

Role.java

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

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long     id;

    @NotNull
    private RoleEnum role;

    // @ManyToMany / @ManyToOne
    @JoinColumn(name = "user")
    private User user;

    [Getters & Setters]

Sample Table

+----+------+------------------------+
| id | role | user                   |
+----+------+------------------------+
|  1 |    0 | digby.tyson@gmail.com  |
|  2 |    1 | digby.tyson@gmail.com  |
|  3 |    2 | digby.tyson@gmail.com  |
|  4 |    3 | digby.tyson@gmail.com  |
|  5 |    4 | digby.tyson@gmail.com  |
|  6 |    5 | digby.tyson@gmail.com  |
|  7 |    6 | digby.tyson@gmail.com  |
|  8 |    7 | digby.tyson@gmail.com  |
|  9 |    5 | ronny.polley@gmail.com |
| 10 |    6 | ronny.polley@gmail.com |
| 11 |    7 | reed.robert@gmail.com  |
+----+------+------------------------+

Thanks for any feedback, I have tried to solve this issue for over a day, so it would be much appreciated.

SJC
  • 2,767
  • 4
  • 20
  • 31
  • 1
    Delete a `Role` with a corresponding `User` is a very strange thing. `Role` is a reference as usual. – v.ladynev Mar 17 '16 at 10:12
  • @v.ladynev `Role` is acting as a permission in this scenario, and the table just stores all `roles` associated with a `User` so when the `User` no longer `exists them entries are no longer needed. – SJC Mar 17 '16 at 10:15
  • 1
    It should be named as the `Permission`, isn't it? – v.ladynev Mar 17 '16 at 10:16
  • @v.ladynev I agree, it should be, and eventually it would be, however my main task it to get what is already written working, then I can refactor – SJC Mar 17 '16 at 10:18
  • 1
    do you realize you need a join table with many-to-many or a unidirectional one-to-many? – Ramanlfc Mar 17 '16 at 10:24
  • @Ramanlfc I did not, I am new to Hibernate and its annotations, so was asking for guidance in this endeavor. WouldI do this with a `@JoinTable` annotation and of so which side do you recommend? Also in your opinion is many-to-many or one-to-many the best way to go? – SJC Mar 17 '16 at 10:28
  • Based on your scenario, what you're likely to want is many-to-many association between `Role` and `User`. Many-to-Many relationship would need a join table which only has user id and role id. With a many-to-many relationship your `Role` class would need to have a `Collection users` and `User` class need to have `Collection roles` – Bunti Mar 17 '16 at 10:34
  • read this and decide what relationship you want , otherwise it's difficult to answer your question if you aren't sure about what relationship you need http://www.objectdb.com/api/java/jpa/annotations/relationship – Ramanlfc Mar 17 '16 at 10:38
  • @Bunti Thanks for that, I did what you said, and it does update the database now. However I have noticed that the `role` table which has an incremental id and `role` (in the form of a number), does not get deleted when the `user_role` join table does. – SJC Mar 17 '16 at 11:01
  • I cannot confidently say anything without seeing the updated source code you have. Normally you have to delete manually any fields, in your case `role` which are still there. This makes sense because this same role can be associated to some other user(because it is many-to-many). I'm off to bed now. You can find a similar answer [here](http://stackoverflow.com/questions/1082095/how-to-remove-entity-with-manytomany-relationship-in-jpa-and-corresponding-join) on how to delete this type of relationship – Bunti Mar 17 '16 at 11:21
  • @Ramanlfc I think now after looking into the relationship I need a Unidirectional OneToMany. This is because there is no way to update a Role. You can only create one and assign it to the 'User' Roles list. The roles of a 'User' will be altered by adding or removing them in the User's Roles list. Can you give me a heads up on how to implement this. I have been trying to solve this issue for the last few days. – SJC Mar 17 '16 at 12:49
  • try this : `@JoinTable(name="user_roles", joinColumns = @JoinColumn(name="user_id"),inverseJoinColumns = @JoinColumn(name="role_id")) @OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true) private List userRoles = new ArrayList();` – Ramanlfc Mar 17 '16 at 15:05
  • @Ramanlfc I tried what you suggested, but I am getting an error `Unable to build Hibernate SessionFactory` when I try and run the app. **User.java** `@JoinTable(name="user_roles", joinColumns = @JoinColumn(name="email"),inverseJoinColumns = @JoinColumn(name="role_id")) @OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true) private List userRoles = new ArrayList();` **Role.java** `@ManyToOne private User user;` – SJC Mar 17 '16 at 16:37
  • It seems you are asking the same question again.Did the last answer not satisfy? [Updating oneToMany entity sets parent to null](http://stackoverflow.com/questions/36050088/updating-onetomany-entity-sets-parent-to-null/36073666#36073666) – K.Nicholas Mar 19 '16 at 18:24

0 Answers0