Problem using Seam identity management with User -> Role link table
lanroth Jan 12, 2010 6:18 PMHi there,
I'm trying to record information about the relationship between a user and a role. Specifically the period of time that the user is or was in a role. Later I want to record which user created the relationship.
To store this information I created a UserAccountRole entity which links the UserAccount and UserRole entities.
I've replaced the existing @ManyToMany relationship between UserAccount and UserRole with @ManyToOne relationships in UserAccountRole.
Here's the code I've got so far:
Note: I've removed all simple unannotated getters/setters for brievity.
@Entity @Table(name="USER_ACCOUNT") public class UserAccount implements Serializable { private long id; private String username; private String password; private String fullName; private Set<UserAccountRole> userAccountRoles=new HashSet<UserAccountRole>(); @Id @GeneratedValue public long getId() { return id; } @UserPrincipal public String getUsername() { return username; } @UserPassword(hash = "none") public String getPassword() { return password; } @UserRoles @OneToMany(mappedBy="userAccount") @Column(name="USER_ACCOUNT_ROLE") public Set<UserAccountRole> getUserAccountRoles() { return userAccountRoles; } } @Entity @Table(name="USER_ROLE") public class UserRole implements Serializable { private Long id; private String name; private String description; private Set<UserRole> groups; @RoleGroups @ManyToMany @JoinTable( name = "user_role_group", joinColumns = @JoinColumn(name = "id"), inverseJoinColumns = @JoinColumn(name = "member_of_role")) public Set<UserRole> getGroups() { return groups; } @Id @GeneratedValue public Long getId() { return id; } @RoleName @Length(max = 20) public String getName() {return name;} } @Entity @Table(name="USER_ACCOUNT_ROLE") public class UserAccountRole implements Serializable{ private Long id; private Date startDate; private Date endDate; private UserAccount userAccount; private UserRole userRole; @Id @GeneratedValue public Long getId() {return id;} @ManyToOne public UserAccount getUserAccount() {return userAccount;} @ManyToOne public UserRole getUserRole() { return userRole; } }
My components.xml has:
<security:jpa-identity-store user-class="org.example.entity.user.UserAccount" role-class="org.example.entity.user.UserRole"/>
When I try to login I get [SeamLoginModule] Error invoking login method in the log.
When I debug into the login I determined that the exception being thrown is:
java.lang.IllegalArgumentException: Could not invoke method by reflection: UserRole.getName() on: org.example.entity.user.UserAccountRole
It looks to me that UserRole.getName() is being called on an object of type UserAccountRole which is clearly wrong but I'm not sure what to do from here. Any ideas?
And the stack at this point looks like:
Daemon Thread [http-0.0.0.0-8080-1] (Suspended (breakpoint at line 150 in Reflections)) Reflections.invokeAndWrap(Method, Object, Object...) line: 150 AnnotatedBeanProperty<T>.getValue(Object) line: 115 JpaIdentityStore.getImpliedRoles(String) line: 719 IdentityManager.getImpliedRoles(String) line: 254 SeamLoginModule.login() line: 130 NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method] NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39 DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25 Method.invoke(Object, Object...) line: 597 LoginContext.invoke(String) line: 769 LoginContext.access$000(LoginContext, String) line: 186 LoginContext$5.run() line: 706 AccessController.doPrivileged(PrivilegedExceptionAction<T>, AccessControlContext) line: not available [native method] LoginContext.invokeCreatorPriv(String) line: 703 LoginContext.login() line: 575 Identity.authenticate(LoginContext) line: 344 Identity.authenticate() line: 332 Identity.login() line: 259 NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method] NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39 DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25 Method.invoke(Object, Object...) line: 597 ReflectionUtil.invokeMethod(Object, Method, Object[]) line: 335 ReflectionUtil.invokeMethod(Object, Object, Class[], Object[]) line: 348 AstPropertySuffix.invoke(Object, EvaluationContext, Class[], Object[]) line: 58 AstValue.invoke(EvaluationContext, Class[], Object[]) line: 96 MethodExpressionImpl.invoke(ELContext, Object[]) line: 276 TagMethodExpression.invoke(ELContext, Object[]) line: 68 MethodBindingMethodExpressionAdapter.invoke(FacesContext, Object[]) line: 88 ActionListenerImpl.processAction(ActionEvent) line: 102 HtmlCommandButton(UICommand).broadcast(FacesEvent) line: 387 AjaxViewRoot.processEvents(FacesContext, EventsQueue, boolean) line: 321 AjaxViewRoot.broadcastEvents(FacesContext, PhaseId) line: 296 AjaxViewRoot.processPhase(FacesContext, PhaseId, InvokerCallback) line: 253 AjaxViewRoot.processApplication(FacesContext) line: 466 InvokeApplicationPhase.execute(FacesContext) line: 82 InvokeApplicationPhase(Phase).doPhase(FacesContext, Lifecycle, ListIterator<PhaseListener>) line: 100 LifecycleImpl.execute(FacesContext) line: 118 FacesServlet.service(ServletRequest, ServletResponse) line: 265 ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 290 ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 206 SeamFilter$FilterChainImpl.doFilter(ServletRequest, ServletResponse) line: 83 IdentityFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 40 SeamFilter$FilterChainImpl.doFilter(ServletRequest, ServletResponse) line: 69 MultipartFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 90 SeamFilter$FilterChainImpl.doFilter(ServletRequest, ServletResponse) line: 69 ExceptionFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 64 SeamFilter$FilterChainImpl.doFilter(ServletRequest, ServletResponse) line: 69 RedirectFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 45 SeamFilter$FilterChainImpl.doFilter(ServletRequest, ServletResponse) line: 69 ConfigurableXMLFilter(BaseXMLFilter).doXmlFilter(FilterChain, HttpServletRequest, HttpServletResponse) line: 178 Filter(BaseFilter).handleRequest(HttpServletRequest, HttpServletResponse, FilterChain) line: 290 Filter(BaseFilter).processUploadsAndHandleRequest(HttpServletRequest, HttpServletResponse, FilterChain) line: 368 Filter(BaseFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 495 Ajax4jsfFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 56 SeamFilter$FilterChainImpl.doFilter(ServletRequest, ServletResponse) line: 69 LoggingFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 60 SeamFilter$FilterChainImpl.doFilter(ServletRequest, ServletResponse) line: 69 HotDeployFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 53 SeamFilter$FilterChainImpl.doFilter(ServletRequest, ServletResponse) line: 69 SeamFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 158 ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 235 ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 206 ReplyHeaderFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 96 ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 235 ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 206 StandardWrapperValve.invoke(Request, Response) line: 235 StandardContextValve.invoke(Request, Response) line: 191 SecurityAssociationValve.invoke(Request, Response) line: 190 NonLoginAuthenticator(AuthenticatorBase).invoke(Request, Response) line: 433 JaccContextValve.invoke(Request, Response) line: 92 SecurityContextEstablishmentValve.process(Request, Response, HttpEvent) line: 126 SecurityContextEstablishmentValve.invoke(Request, Response) line: 70 StandardHostValve.invoke(Request, Response) line: 127 ErrorReportValve.invoke(Request, Response) line: 102 CachedConnectionValve.invoke(Request, Response) line: 158 StandardEngineValve.invoke(Request, Response) line: 109 CoyoteAdapter.service(Request, Response) line: 330 Http11Processor.process(Socket) line: 829 Http11Protocol$Http11ConnectionHandler.process(Socket) line: 598 JIoEndpoint$Worker.run() line: 447 Thread.run() line: 619