0

I have problem, becouse I don't know how to remove specific role from User. This problem is connected with unidirectional relation in Permission class. These are only relevant code snippets.

Class Person

@Entity
public class User {

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

@OneToMany(cascade = CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="user")
private Collection<Role> roles;

Class Role

@Entity
public class Role {

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

@ManyToOne( fetch=FetchType.LAZY)
private User user;

I tried to remove specific Role from User in this way

user.getRoles().remove(roleToRemove)
entityManger.merge(user)

roleToRemove was deleted from Collection but not from datebase. (I wrote test which were completed)

So, i added

 orphanRemoval = true

And currently I have problem with unidirectional relationship which occurs in Permission class. I receives DatabaseExepction becouse idRole which I want remove, exists in Permision table.

 @Entity
public class Permission {

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

@ManyToOne( fetch=FetchType.LAZY)
private Role role;

So, My question is how to manage with this problem.

2 Answers2

-1

Hello the User is not the owner of the relationship User - Role. You need to update the owning end of the relationship in order to make it work.

user.getRoles().remove(roleToRemove)
roleToRemove.setUser(null)
entityManger.merge(user)

My understanding is that you don't need orphan removal.

Alexander Petrov
  • 9,204
  • 31
  • 70
-1

This isn't unidirectional - it is a bidirectional relationship. You need to maintain both sides of your user-role relationship for the object model to reflect the database. It is just good practice and avoids issues like these to have your code manage both sides of any relationship. Since you are already removing the role from the user's roles collection, you also need to null out the Role's reference to user and merge both the user and the role.

the owning side controls the foreign key in the database, so only 1 update statement will occur that affect the role row, but your object model will be in synch with the database, preventing caches from becoming out of synch as well.

Chris
  • 20,138
  • 2
  • 29
  • 43
  • Did you notice that I have addressed this in my answer - "relationship owner" and "updating the relationship from both ends"? If you think that more details are needed you should have posted on my answer. Playing the parrot game with improving the write style I don't find it as a demonstration of good taste. – Alexander Petrov Jul 21 '16 at 18:28
  • Style and taste are in the eye of the beholder, but your answer is only half right as it didn't mention that the role needs to be merged. Feel free to update your answer with more information if you want it to be complete and more useful to people who might encounter similar issues - I'll happily remove mine if you cover it all. Otherwise, the OP can decide the 'best' answer - after all, that is the point of allowing multiple answers on sites like these. – Chris Jul 21 '16 at 18:45
  • Well that is a terrible delusion. Merging on both ends is 100% un necessary. http://stackoverflow.com/questions/20068742/jpa-updating-bidirectional-association I think you should give me now one vote for opening your eyes:) – Alexander Petrov Jul 21 '16 at 18:52
  • Uh, I think you misread the answer you linked to and is why my answer was absolutely needed. If you have cascade merge on the relationship, that works when you add a reference, but how on earth will cascade merge find the changes to role if it is no longer referenced? If you are working with detached entities, you need to explicitly merge BOTH back into the persistence unit. Otherwise, merge isn't needed at all. – Chris Jul 21 '16 at 19:03
  • How do you know that she is working with detached entities ? Did she wrote in the question what her sequence is ? No. You are as right as I am . Which mean Context based rightness. – Alexander Petrov Jul 21 '16 at 19:10
  • PS for someone just starting answering questions, you might want to tone down calling others delusional and dictating what is or isn't good taste. As for what you know or don't know - if you are assuming they are attached, why does your 'answer' have a merge call in it? While your answer may work for this situation if both entities are managed, it is not really a complete answer now is it? – Chris Jul 21 '16 at 19:11
  • @Alexander Petrov If you feel this answer can be improved on, explain how. I've already stated if you expanded on your answer, I would remove mine, so downvoting because it is similar to yours is just being childish - I would hope you wouldn't be so childish on account where you linked your professional profile. You do know that any employer that cares about your reputation would also care about your professionalism and the quality of your answers? – Chris Jul 21 '16 at 19:20
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/117968/discussion-between-chris-and-alexander-petrov). – Chris Jul 21 '16 at 19:57