2 Replies Latest reply on Jul 10, 2008 5:50 PM by stefanotravelli

    DB not refreshed (JPA problem)

    tomaszatwork

      I want to crete the generic user roles concept with seam. The user can have many roles. The roles selves can have their own child roles. To realize this i created 4 tables


      orcuser(id, username, pass)
      orc
      roles(id, name, description)
      orcuserrole(userID, roleID)
      orcrolerole(parentID, childID)


      then i used seam reverse engineering tool to create the entity beans.


      if i execute the following code:


      OrcRoles parent = em.find(OrcRoles.class, parent.getId());
      ArrayList<OrcRoleRole> roles = parent.getOrcRoleRolesForParentId();
      roles.remove(roles.iterator().next());
      em.merge(parent);
      em.flush();
      




      the hibernate do not remove the first roleroleItem item from the database.


      How can i persuade JPA/Hibernade to remove the manipulated Set elements from DB?





      package de.h2o.common.entities.entity;
      // Generated 07.07.2008 15:04:14 by Hibernate Tools 3.2.0.CR1
      
      import java.util.HashSet;
      import java.util.Set;
      import javax.persistence.CascadeType;
      import javax.persistence.Column;
      import javax.persistence.Entity;
      import javax.persistence.FetchType;
      import javax.persistence.GeneratedValue;
      import static javax.persistence.GenerationType.IDENTITY;
      import javax.persistence.Id;
      import javax.persistence.OneToMany;
      import javax.persistence.Table;
      import org.hibernate.validator.NotNull;
      
      /**
       * OrcRoles generated by hbm2java
       */
      @Entity
      @Table(name = "orc_roles", catalog = "test")
      public class OrcRoles implements java.io.Serializable {
      
        private Long id;
        private String name;
        private String description;
        private Set<OrcRoleRole> orcRoleRolesForParentId = new HashSet<OrcRoleRole>(
            0);
        private Set<OrcUserRole> orcUserRoles = new HashSet<OrcUserRole>(0);
        private Set<OrcRoleRole> orcRoleRolesForChildId = new HashSet<OrcRoleRole>(
            0);
      
        public OrcRoles() {
        }
      
        public OrcRoles(String name) {
          this.name = name;
        }
        public OrcRoles(String name, String description,
            Set<OrcRoleRole> orcRoleRolesForParentId,
            Set<OrcUserRole> orcUserRoles,
            Set<OrcRoleRole> orcRoleRolesForChildId) {
          this.name = name;
          this.description = description;
          this.orcRoleRolesForParentId = orcRoleRolesForParentId;
          this.orcUserRoles = orcUserRoles;
          this.orcRoleRolesForChildId = orcRoleRolesForChildId;
        }
      
        @Id
        @GeneratedValue(strategy = IDENTITY)
        @Column(name = "id", unique = true, nullable = false)
        public Long getId() {
          return this.id;
        }
      
        public void setId(Long id) {
          this.id = id;
        }
      
        @Column(name = "name", nullable = false)
        @NotNull
        public String getName() {
          return this.name;
        }
      
        public void setName(String name) {
          this.name = name;
        }
      
        @Column(name = "description")
        public String getDescription() {
          return this.description;
        }
      
        public void setDescription(String description) {
          this.description = description;
        }
        @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "orcRolesByParentId")
        public Set<OrcRoleRole> getOrcRoleRolesForParentId() {
          return this.orcRoleRolesForParentId;
        }
      
        public void setOrcRoleRolesForParentId(
            Set<OrcRoleRole> orcRoleRolesForParentId) {
          this.orcRoleRolesForParentId = orcRoleRolesForParentId;
        }
        @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "orcRoles")
        public Set<OrcUserRole> getOrcUserRoles() {
          return this.orcUserRoles;
        }
      
        public void setOrcUserRoles(Set<OrcUserRole> orcUserRoles) {
          this.orcUserRoles = orcUserRoles;
        }
        @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "orcRolesByChildId")
        public Set<OrcRoleRole> getOrcRoleRolesForChildId() {
          return this.orcRoleRolesForChildId;
        }
      
        public void setOrcRoleRolesForChildId(
            Set<OrcRoleRole> orcRoleRolesForChildId) {
          this.orcRoleRolesForChildId = orcRoleRolesForChildId;
        }
      
      }
      



      package de.h2o.common.entities.entity;
      // Generated 07.07.2008 15:04:14 by Hibernate Tools 3.2.0.CR1
      
      import javax.persistence.AttributeOverride;
      import javax.persistence.AttributeOverrides;
      import javax.persistence.Column;
      import javax.persistence.EmbeddedId;
      import javax.persistence.Entity;
      import javax.persistence.FetchType;
      import javax.persistence.JoinColumn;
      import javax.persistence.ManyToOne;
      import javax.persistence.Table;
      import org.hibernate.validator.NotNull;
      
      /**
       * OrcRoleRole generated by hbm2java
       */
      @Entity
      @Table(name = "orc_role_role", catalog = "test")
      public class OrcRoleRole implements java.io.Serializable {
      
              private OrcRoleRoleId id;
              private OrcRoles orcRolesByChildId;
              private OrcRoles orcRolesByParentId;
      
              public OrcRoleRole() {
              }
      
              public OrcRoleRole(OrcRoleRoleId id, OrcRoles orcRolesByChildId,
                              OrcRoles orcRolesByParentId) {
                      this.id = id;
                      this.orcRolesByChildId = orcRolesByChildId;
                      this.orcRolesByParentId = orcRolesByParentId;
              }
      
              @EmbeddedId
              @AttributeOverrides({
                              @AttributeOverride(name = "parentId", column = @Column(name = "parentID", nullable = false)),
                              @AttributeOverride(name = "childId", column = @Column(name = "childID", nullable = false))})
              @NotNull
              public OrcRoleRoleId getId() {
                      return this.id;
              }
      
              public void setId(OrcRoleRoleId id) {
                      this.id = id;
              }
              @ManyToOne(fetch = FetchType.LAZY)
              @JoinColumn(name = "childID", nullable = false, insertable = false, updatable = false)
              @NotNull
              public OrcRoles getOrcRolesByChildId() {
                      return this.orcRolesByChildId;
              }
      
              public void setOrcRolesByChildId(OrcRoles orcRolesByChildId) {
                      this.orcRolesByChildId = orcRolesByChildId;
              }
              @ManyToOne(fetch = FetchType.LAZY)
              @JoinColumn(name = "parentID", nullable = false, insertable = false, updatable = false)
              @NotNull
              public OrcRoles getOrcRolesByParentId() {
                      return this.orcRolesByParentId;
              }
      
              public void setOrcRolesByParentId(OrcRoles orcRolesByParentId) {
                      this.orcRolesByParentId = orcRolesByParentId;
              }
              
              public String toString() {
                return "OrcRoleRole(parentId:" + id.getParentId() + ", childId:" + id.getChildId() + ")"; 
              }
      
      }
      



        • 1. Re: DB not refreshed (JPA problem)
          tomaszatwork

          the tables i have create are:



          orc_user(id, username, pass) 
          
          orc_roles(id, name, description) 
          
          orc_user_role(userID, roleID) 
          
          orc_role_role(parentID, childID) 


          • 2. Re: DB not refreshed (JPA problem)
            stefanotravelli

            A reverse engineering approach (make db tables first and then generate classes) it's not a recommended approach unless you have an untouchable legacy db schema to manage.


            Even in this case 'orcuserrole' and 'orcrolerole' are clearly many-to-many relationships and you shouldn't map them as entities.


            That said, the collections are not updated because they are mappedBy, that is read-only or inverse in Hibernate speaking.
            In order to delete the relationship you have to issue a remove on the OrcRoleRole object.


            I suggest to read the Hibernate documentation about how to map a many-to-many relationship.


            Also note that your particular use case is fully covered by the new security features in Seam 2.1, so if you could wait for that version to be released you neither have to write the code to manage users/roles because it's already done in the new IdentityManager/IdentityStore components.


            Hope this helps.