7 Replies Latest reply on Feb 14, 2009 5:57 PM by Michael Wohlfart

    Does @UserRoles only works in ManyToMany-Relation ?

    nimo stephan Master

      Hello,


      I have three Entity-Beans:



      User
      User_Roles
      Roles




      Now I assign my UserRoles in my EntityBean User:



      @UserRoles
      @OneToMany(..)
      public Set<User_Roles> getUser_Roles() {
      ..
      }




      This does not work. I get the failure:


      Caused by: java.lang.RuntimeException: Exception getting bean property
              at org.jboss.seam.util.AnnotatedBeanProperty.getValue(AnnotatedBeanProperty.java:132)
      ...
      
      Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
      ..






      So I assume, that this only works by declaring a @ManyToMany explicitly instead of @OneToMany, because in my case the UserRolesProperty returns the UserRoles-Instance instead of the Roles-Instance.


      However, I have additional attributes in User
      Roles and cannot use the @ManyToMany-Relation.


      Any Suggestions?

        • 1. Re: Does @UserRoles only works in ManyToMany-Relation ?
          Francisco Jose Peredo Noguez Master

          I don't get your question... was the @UserRoles annotation created by you? with what purpose?


          If you have 3 entity beans: User, User_Roles, Roles, first you are going against the naming conventions in Java: User_Roles should be UserRoles (underscores are discouraged). Now, if we assume that you have a class UserRoles, and that is marked with an @Entity annotation, I don't see how it could be used itself as an annotation, I can not make sense from you example:


          @UserRoles
          @OneToMany(..)
          public Set<User_Roles> getUser_Roles() {
          ..
          }
          



          it should be:


          @OneToMany(..)
          public Set<User_Roles> getUser_Roles() {
          ..
          }
          



          or, after removing the _:



          @OneToMany(..)
          public Set<UserRoles> getUserRoles() {
          ..
          }
          



          Can you explain the purpose of @UserRoles annotation? again... did you create it?


          Regards,





          • 2. Re: Does @UserRoles only works in ManyToMany-Relation ?
            nimo stephan Master

            No.


            @UserRoles is a annotation coming from SEAM-Security 
            (SEAM-Reference 2.1: 15.4.2.2. Configuring the Entities)


            It seems that this annotation does not work when I have the Entity-Relationship UserRoles between the two entity User and Roles.


            However, normally I can implement a many-to-many-Relation with two one-to-many-Relations. I have to, because I add columns to my join table (UserRoles).


            How can I use the @UserRoles-Annotation in such a case??



            UserRoles (underscores are discouraged)

            I know, I used it to make the difference of the Annotation @UserRoles and my entity-bean UserRoles clearly.



            • 3. Re: Does @UserRoles only works in ManyToMany-Relation ?
              Francisco Jose Peredo Noguez Master

              Oh, now I get it, you have a ManyToMany relationship but you have extra fields in the intermediate table, and therefore you can not use the ManyToMany annotation, because it hides the intermediate table, but if  you use a pair of ManyToOne/OneToMany relationships and an visible itermediate entity, then you don't know what to do with the @UserRoles annotation... Am I right?


              Mmm... I haven't tried the Seam 2.1 beta, but... have you tried adding a dummy (read-only) ManyToMany relationship (Note the insertable=false,updateable=false)?


              @UserRoles
              
                @ManyToMany(targetEntity = Role.class, insertable=false,updateable=false)
              
                @JoinTable(name = "UserRoles", 
              
                  joinColumns = @JoinColumn(name = "UserId"),
              
                  inverseJoinColumns = @JoinColumn(name = "RoleId"))
              
                public Set<Role> getRoles() { return roles; }
              
                public void setRoles(Set<Role> roles) { this.roles = roles; }
              
              }
              



              This way the ManyToMany would only be used for read-only stuff... of course you need to remember to refresh stuff after modifying the relationship using the real (writable) relationship.


              Hope this helps,


              • 4. Re: Does @UserRoles only works in ManyToMany-Relation ?
                Shane Bryzak Master

                I don't think that we currently support cross reference tables in this manner, although we should.  Please raise this as an issue in JIRA and assign to me.

                • 5. Re: Does @UserRoles only works in ManyToMany-Relation ?
                  nimo stephan Master

                  Hello Francisco,




                  thanks, but this does not help as it will not include the ternary relationship accordingly. (Imagine you have the Entities User, Roles, Organisation with a ternary relationship. You need the roles of a User of a particular Organisation. @UserRoles does not work in such case)



                  Hello Shane,



                  I have never assigned an issue in JIRA, I will try to do :-)



                  However, to use SEAM-Security, I need the @UserRoles-Annotation.


                  I have left this:


                  @UserRoles
                  @OneToMany(..)
                  public Set<User_Roles> getUser_Roles() {
                  ..
                  }



                  I have overrided the JPAIdentityStore to get the Roles considering my ternary relationship. It seems, it works:



                  @Name("org.jboss.seam.security.jpaIdentityStore")
                  @Install(precedence = DEPLOYMENT)
                  @Scope(APPLICATION)
                  @BypassInterceptors
                  @Startup
                  public class MyIdentityStore implements IdentityStore, Serializable
                  {
                  ...
                  // These methods I have changed to match the roles
                  public List<String> getGrantedRoles(String name){..}
                  
                  public List<String> getImpliedRoles(String name) {..}
                  
                  public boolean grantRole(String username, String role){..}
                  
                  public boolean revokeRole(String username, String role){..}
                  
                  ..
                  }



                  As I am fearing of having any negative (invisible) side-effects, I have the following question:


                  - Have I considered all the methods that must be overriden ???




                  Thanks for helping:-)





                  Note:
                  public class MyIdentityStore implements IdentityStore
                  does not need all the @Override-Annotations. So I decided to use this instead of MyIdentityStore extends JPAIdentityStore.

                  • 6. Re: Does @UserRoles only works in ManyToMany-Relation ?
                    nimo stephan Master

                    Okay, now it s clear..all works.


                    thanks.

                    • 7. Re: Does @UserRoles only works in ManyToMany-Relation ?
                      Michael Wohlfart Expert

                      Did anybody get this working ?


                      according to https://jira.jboss.org/jira/browse/JBSEAM-3466
                      this should be working now, however I get:



                      ERROR SeamLoginModule Error invoking login method
                      java.lang.IllegalArgumentException: 
                      Could not invoke method by reflection: Role.getName() on: some.package.UserRoles
                       at org.jboss.seam.util.Reflections.invoke(Reflections.java:32)
                       at org.jboss.seam.util.Reflections.invokeAndWrap(Reflections.java:144)
                       at org.jboss.seam.util.AnnotatedBeanProperty.getValue(AnnotatedBeanProperty.java:115)
                       at org.jboss.seam.security.management.JpaIdentityStore.getImpliedRoles(JpaIdentityStore.java:698)
                       at org.jboss.seam.security.management.IdentityManager.getImpliedRoles(IdentityManager.java:254)





                      to me it looks like IdentityManager.getImpliedRoles doesn't
                      use the xref class, can anyone confirm that? Or am i missing something here ?