1 Reply Latest reply on Aug 18, 2008 10:46 AM by mantay

    Problems updating entity in a many-to-many relationship

    mantay

      Hi all,

      I have a many-to-many relationship between entities User and Permission. Since I need an additional field "isDenied" in the association table, I cannot use the @Many-to-many annotation, but have to model this table explicitly an an entity UserPermission. I create a one-to-many relationship between User and UserPermission and another one between Permission and UserPermission.The modelling direction ("write direction") is from UserPermission to User and Permission, respectively.

      Reading entities UserPermission from the database and storing new ones into it works fine. However, removing them does not work when invoking the entity manager's merge method on a user object. For instance, if user entity u1 is associated to permission p1, and I remove the association (u1, p1) from user.getUserPermissions() and add (u1, p2) followed by the invocation entityManager.merge(u1), I end up with two relationships (u1, p1) and (u1, p2) in the DB instead of just (u1, p2) which is what I would have expected. In the debugger I see that user.getUserPermissions() yields a list with (u1, p2) as the only entry which has no id. The association (u1, p1) is not present in this list. So why doesn't entityManager.merge(u1) remove (u1, p1) from the database?

      Best regards,
      Thomas

      Here is a code snippet of my modelling (unimportant parts are left out):

      Entity User:

      @Entity
      @Table(name = "USERS", uniqueConstraints = @UniqueConstraint(columnNames = "USERNAME"))
      @SequenceGenerator(name = "SEQ", sequenceName = "SE_USERS_ID", allocationSize = 1)
      public class User extends Persistent implements java.io.Serializable
      {
      private List<UserPermission> userPermissions = new ArrayList<UserPermission>(0);
      
      @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "user")
      public List<UserPermission> getUserPermissions()
      {
      return this.userPermissions;
      }
      
      public void setUserPermissions(List<UserPermission> userPermissions)
      {
      this.userPermissions = userPermissions;
      }
      }
      


      Entity UserPermission:

      @Entity
      @Table(name = "USERS_PERMISSION")
      @SequenceGenerator(name = "SEQ", sequenceName = "SE_USERS_PERMISSION_ID", allocationSize = 1)
      public class UserPermission extends Persistent implements Serializable
      {
      private Boolean isDenied;
      
      private User user;
      
      private Permission permission;
      
      @ManyToOne
      @JoinColumn(name = "USER_ID")
      public User getUser()
      {
      return user;
      }
      
      public void setUser(User user)
      {
      this.user = user;
      }
      
      @ManyToOne
      @JoinColumn(name = "PERMISSION_ID")
      public Permission getPermission()
      {
      return permission;
      }
      
      public void setPermission(Permission permission)
      {
      this.permission = permission;
      }
      
      @Column(name = "IS_DENIED")
      public Boolean getDenied()
      {
      return isDenied;
      }
      
      public void setDenied(Boolean isDenied)
      {
      this.isDenied = isDenied;
      }
      }
      


      Entity Permission:

      @Entity
      @Table(name = "PERMISSION", uniqueConstraints = @UniqueConstraint(columnNames = "OBJECT_NAME"))
      @SequenceGenerator(name = "SEQ", sequenceName = "SE_PERMISSION_ID", allocationSize = 1)
      public class Permission extends Persistent implements java.io.Serializable
      {
      private List<UserPermission> userPermissions = new ArrayList<UserPermission>(0);
      
      @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "permission")
      public List<UserPermission> getUserPermissions()
      {
      return this.userPermissions;
      }
      
      public void setUserPermissions(List<UserPermission> userPermissions)
      {
      this.userPermissions = userPermissions;
      }
      }
      



        • 1. Re: Problems updating entity in a many-to-many relationship
          mantay

          One solution to my problem is to find out the UserPermissions to be deleted and remove them manually using the entity manager's remove method. I think it's a bit strange that this cannot be done by the container. After all it is able to store new relationships in the DB and update existing ones. So it should be able to remove existing ones as well.

          Anyways, things work the way I described, albeit my code looks all cluttered now. :-/

          Regards,
          Thomas