2 Replies Latest reply on Feb 16, 2009 9:28 PM by Michael Pöhlmann

    identity manager - duplicate identity created on new user creation with runasoperation

    Michael Pöhlmann Newbie

      Hi there,


      I am very new to JBoss seam and had some experiments in the last two weaks. I am going to build an application where user should be able to register by themselve. Later this will be a double opt-in feature with activation code and so on.
      Right now I tried to get the components drools and jpaIdentityStore (with user and roles) to work. After some days and reading lots of posts here drools worked fine (putting the jar on the rigth place).
      Yesterday I tried to implement a proper way of the registration process looking at the seamspace example. I Tried to get as closed as possible to the example cause it should work very well for me.
      But I wasn't able to get my implementation to work correct.


      Now the details (using JBoss 4.2.3 GA, jre 1.5.0_17, jboss-seam 2.1.1 GA):


      The registration form is very simple only containing an username, email address and password (with verify). When one clicks on the button the following root cause of exception can be found in the output: javax.persistence.NonUniqueResultException: result returns 2 elements


      I searched in the for forum for several days now, but did not really find a solution for my problem. Only one similar thread http://www.seamframework.org/Community/IdentityManagerDuplicateUserRoleMappingCreatedOnNewUserCreation which similar but not exactly the same issue.


      Thank You very much for any suggestions!


      Let's have a look at my implementation now (the package name here is alway shortened to read ...).


      components.xml



      <?xml version="1.0" encoding="UTF-8"?>
      <components xmlns="http://jboss.com/products/seam/components"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:core="http://jboss.com/products/seam/core"
           xmlns:persistence="http://jboss.com/products/seam/persistence"
           xmlns:mail="http://jboss.com/products/seam/mail"
           xmlns:security="http://jboss.com/products/seam/security"
           xmlns:drools="http://jboss.com/products/seam/drools"
           xsi:schemaLocation="
                http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.1.xsd
                http://jboss.com/products/seam/persistence http://jboss.com/products/seam/persistence-2.1.xsd
                http://jboss.com/products/seam/mail http://jboss.com/products/seam/mail-2.1.xsd
                http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.1.xsd
                http://jboss.com/products/seam/drools http://jboss.com/products/seam/drools-2.1.xsd
                http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.1.xsd
           ">
           <core:init debug="true" jndi-pattern="@jndiPattern@"/>
           <core:manager
                concurrent-request-timeout="500"
                conversation-timeout="120000"
                conversation-id-parameter="cid"
                parent-conversation-id-parameter="pid"/>
           <drools:rule-base name="securityRules">
                <drools:rule-files>
                     <value>/META-INF/security-rules.drl</value>
                </drools:rule-files>
           </drools:rule-base>
           <security:rule-based-permission-resolver security-rules="#{securityRules}"/>
           <persistence:managed-persistence-context
                name="entityManager"
                auto-create="true"
                persistence-unit-jndi-name="java:/siteEntityManagerFactory"/>
           <security:identity-manager identity-store="#{jpaIdentityStore}" role-identity-store="#{jpaIdentityStore}"/>
           <security:jpa-identity-store
                user-class="...entity.user.IdentityUser"
                role-class="...entity.user.IdentityRole"/>
           <mail:mail-session host="localhost" port="25" username="michael" password="..."/>
      </components>
      



      IdentityUser



      // imports ...
      @Entity
      @Name("identityUser")
      @Table(name="mm_identityuser",uniqueConstraints = @UniqueConstraint(columnNames="username"))
      public class IdentityUser implements Serializable {
           private static final long serialVersionUID = 5L;
           
           private String id;
           private SiteUser siteUser;
           private Set<IdentityRole> roles;
           private String username;
           private String password;
           private boolean enabled;
      
           @Id
           @GeneratedValue(generator="gen_user_id")
           @GenericGenerator(name="gen_user_id", strategy="uuid")
           public String getId() {
                return id;
           }
           public void setId(String id) {
                this.id = id;
           }
           
           // having own user details here ...
           @OneToOne(targetEntity=SiteUser.class)
           @JoinColumn(name="siteuser_id")
           public SiteUser getSiteUser() {
                return siteUser;
           }
           public void setSiteUser(SiteUser siteUser) {
                this.siteUser = siteUser;
           }  
           
           @UserRoles
           @ManyToMany(targetEntity = IdentityRole.class)
           @JoinTable(name="mm_identityuserroles",
                joinColumns = @JoinColumn(name = "identityuserid"),
                inverseJoinColumns = @JoinColumn(name = "identityroleid"))
           public Set<IdentityRole> getRoles() {
                return roles;
           }
           public void setRoles(Set<IdentityRole> roles) {
                this.roles = roles;
           }
             
           @NotNull @UserPrincipal
           public String getUsername() {
                return username;
           }
           public void setUsername(String username) {
                this.username = username;
           }
           
           @UserPassword(hash="md5")
           public String getPassword() {
                return password;
           }
           public void setPassword(String password) {
                this.password = password;
           }
      
           @UserEnabled
           public boolean isEnabled() {
                return enabled;
           }
           public void setEnabled(boolean enabled) {
                this.enabled = enabled;
           }
           
           @Override
           public String toString() {
                return StringUtil.concat(super.toString(), " - IdentityUser[username=", username, "]");
           }
      }
      



      SiteUser



      // imports ...
      @Entity
      @Name("siteUser")
      @Table(name="mm_siteuser")
      public class SiteUser implements Serializable {
           private static final long serialVersionUID = 5L;
      
           private String id;
           private String activationcode;
           private String email;
           private Date registrationDate;
           
           @Id
           @GeneratedValue(generator="gen_user_id")
           @GenericGenerator(name="gen_user_id", strategy="uuid")
           public String getId() {
                return id;
           }
           public void setId(String id) {
                this.id = id;
           }
           
           @Column(length=32)
           public String getActivationcode() {
                return activationcode;
           }
           public void setActivationcode(String activationcode) {
                this.activationcode = activationcode;
           }
           
           @NotNull
           @Column(length=80, unique=true)
           public String getEmail() {
                return email;
           }
           public void setEmail(String email) {
                this.email = email;
           }
      
           @NotNull
           public Date getRegistrationDate() {
                return registrationDate;
           }
           public void setRegistrationDate(Date registrationDate) {
                this.registrationDate = registrationDate;
           }
           
           @Override
           public String toString() {
                return StringUtil.concat(super.toString(), " - SiteUser[email=", email, "]");
           }
      }
      



      IdentityRole



      // imports ...
      @Entity
      @Table(name="mm_identityrole")
      public class IdentityRole implements Serializable {
           private static final long serialVersionUID = 3L;
           
           private Integer roleId;
           private String rolename;
           private boolean conditional;
           private Set<IdentityRole> groups;
           
           @Id
           @GeneratedValue(generator="gen_user_id")
           @GenericGenerator(name="gen_user_id", strategy="uuid")
           public Integer getRoleId() {
                return roleId;
           }
           public void setRoleId(Integer roleId) {
                this.roleId = roleId;
           }
             
           @RoleName
           public String getRolename() {
                return rolename;
           }
           public void setRolename(String rolename) {
                this.rolename = rolename;
           }
           
           @RoleConditional
           public boolean isConditional() {
                return conditional;
           }
           public void setConditional(boolean conditional) {
                this.conditional = conditional;
           }
           
           @RoleGroups
           @ManyToMany(targetEntity = IdentityRole.class)
           @JoinTable(name="mm_identityrolegroups", 
                joinColumns = @JoinColumn(name="identityroleid"),
                inverseJoinColumns = @JoinColumn(name = "identitygroupid"))
           public Set<IdentityRole> getGroups() {
                return groups;
           }
           public void setGroups(Set<IdentityRole> groups) {
                this.groups = groups;
           }  
      }
      



      register.xhtml



      <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
          xmlns:s="http://jboss.com/products/seam/taglib"
          xmlns:ui="http://java.sun.com/jsf/facelets"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:h="http://java.sun.com/jsf/html"
           xmlns:a="http://richfaces.org/a4j"
          xmlns:rich="http://richfaces.org/rich"
          template="/layout/template.xhtml">
      <ui:define name="body">
           <h:form id="register">
                <rich:panel>
                     <f:facet name="header">#{messages.headerRegister}</f:facet>
                     <s:decorate id="username" template="/layout/ui/edit.xhtml">
                          <ui:define name="label">#{messages.textUser}:</ui:define>
                          <h:inputText id="username" value="#{register.username}" required="true">
                               <a:support id="onblur" event="onblur" reRender="username"/>
                          </h:inputText>
                     </s:decorate>
                     <s:decorate id="email" template="/layout/ui/edit.xhtml">
                          <ui:define name="label">#{messages.textEMail}:</ui:define>
                          <h:inputText id="email" value="#{register.siteUser.email}" required="true">
                               <a:support id="onblur" event="onblur" reRender="email"/>
                          </h:inputText>
                     </s:decorate>
                     <s:decorate id="password" template="/layout/ui/edit.xhtml">
                          <ui:define name="label">#{messages.textPassword}:</ui:define>
                          <h:inputSecret id="password" value="#{register.password}" required="true"/>
                     </s:decorate>
                     <s:decorate id="verify" template="/layout/ui/edit.xhtml">
                          <ui:define name="label">#{messages.textPasswordVerify}:</ui:define>
                          <h:inputSecret id="verify" value="#{register.verify}" required="true"/>
                     </s:decorate>
                     <s:decorate id="register" template="/layout/ui/button.xhtml">
                          <h:commandButton value="#{messages.buttonRegister}" action="#{register.register}"/>
                     </s:decorate>
                </rich:panel>
           </h:form>
      </ui:define>
      </ui:composition>
      



      register.page.xml



      <?xml version="1.0" encoding="UTF-8"?>
      <page xmlns="http://jboss.com/products/seam/pages"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.1.xsd">
           <action execute="#{register.start}" if="#{register.siteUser *null}"/>
           <navigation>
                <rule if="#{register.registered}">
                     <redirect view-id="/user/registrationMailSent.xhtml" />
                </rule>
                <rule if="#{not register.registered}">
                     <redirect view-id="/user/register.xhtml"/>
                </rule>
           </navigation>
      </page>
      



      pages.xml



      <?xml version="1.0" encoding="UTF-8"?>
      <pages xmlns="http://jboss.com/products/seam/pages"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.1.xsd"
           login-view-id="/home.xhtml"
      >
          <page view-id="/home.xhtml">
              <navigation from-action="#{identity.login}">
                  <rule if-outcome="loggedIn">
                      <redirect view-id="/home.xhtml"/>
                  </rule>
              </navigation>
              <navigation from-action="#{register.start}"><!-- does also not work not knowing why -->
                   <rule>
                        <redirect view-id="/user/register.xhtml"/>
                   </rule>
              </navigation>
          </page>
           <exception>
                <redirect view-id="/error.xhtml">
                     <message severity="error">Unexpected error, please try again</message>
                </redirect>
           </exception>
      </pages>
      



      RegisterAction



      // imports ...
      @Stateful
      @Scope(ScopeType.CONVERSATION)
      @Name("register")
      public class RegisterAction implements Register
      {
          @Logger
          private Log log;
      
          @PersistenceContext
          private EntityManager em;
          
          @In
          private IdentityManager identityManager;
          
          private IdentityUser identityUser;
          private SiteUser siteUser;
          
          @In
          private FacesMessages facesMessages;
          
          @In(create=true)
          private Renderer renderer;
          
          private String username;
          private String password;
          private String verify;
          private boolean registered;
          
          @Observer(JpaIdentityStore.EVENT_USER_CREATED)
          public void identityUserCreated(IdentityUser identityUser)
          {
               log.debug("going to persist siteuser details in conjunction to identityuser ...");
               identityUser.setSiteUser(siteUser);
               this.identityUser = identityUser;
               log.info("persisted siteuser details in conjunction to identityuser with activationcode #{siteUser.activationcode}");
          }
          
          @Begin
          public void start() {
               log.debug("going to start registration ...");
               siteUser = new SiteUser();
          }
          @End
          public void register() {
               log.info("register.register() action called for #0", username);
               if (password *null || !password.equals(verify)) {
                     facesMessages.add("Passwords do not match");
                  facesMessages.addToControl("verify", "Re-enter your password");
                  verify = null;
                     return;
               }
               siteUser.setRegistrationDate(new Date());
               siteUser.setActivationcode(getNewActivationcode());
               //em.persist(siteUser); // just a try to remove this line - did not work for me
               
               new RunAsOperation() {
                    @Override
                    public void execute() {
                        log.info("registering new user #0", username);
                        if (identityManager.createUser(username, password)) {
                             // TODO: set initial role
                             //identityManager.grantRole(username, "user");
                        } else {
                             facesMessages.add("Registering user #0 failed", username);
                        }
                    }
               }.addRole("admin").run();
               
               identityUser.setSiteUser(siteUser);
               //identityUser = em.merge(identityUser); // another try, which did not work
               
               registered = true;
               
               facesMessages.add("User #{identityuser.username} successfully registered");
               renderer.render("/user/registrationMail.xhtml"); // send an email to new user
          }
          
          private String getNewActivationcode() {
                // ... some stuff ;)
           }
      
          public boolean isRegistered() {
             return registered;
          }
          
          public SiteUser getSiteUser() {
               return siteUser;
          }
          
          public String getUsername() {
                return username;
           }
           public void setUsername(String username) {
                this.username = username;
           }
      
           public String getPassword() {
                return password;
           }
           public void setPassword(String password) {
                this.password = password;
           }
      
           public String getVerify() {
                return verify;
           }
           public void setVerify(String verify) {
                this.verify = verify;
           }
           
           @Destroy
           @Remove
           public void destroy() {
           }
      }
      



      log with Stacktrace



      19:05:44,407 INFO  [RegisterAction] register.register() action called for michael
      19:05:44,408 INFO  [RegisterAction] registering new user michael
      19:05:44,646 INFO  [STDOUT] Hibernate: 
          select
              identityus0_.id as id2_,
              identityus0_.password as password2_,
              identityus0_.enabled as enabled2_,
              identityus0_.username as username2_,
              identityus0_.siteuser_id as siteuser5_2_ 
          from
              mm_identityuser identityus0_ 
          where
              identityus0_.username=?
      19:05:44,677 INFO  [STDOUT] Hibernate: 
          select
              siteuser0_.id as id3_0_,
              siteuser0_.activationcode as activati2_3_0_,
              siteuser0_.email as email3_0_,
              siteuser0_.registrationDate as registra4_3_0_ 
          from
              mm_siteuser siteuser0_ 
          where
              siteuser0_.id=?
      19:05:44,689 ERROR [application] javax.ejb.EJBTransactionRolledbackException: Could not create account
      javax.faces.el.EvaluationException: javax.ejb.EJBTransactionRolledbackException: Could not create account
           at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
           at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
           at javax.faces.component.UICommand.broadcast(UICommand.java:387)
           at org.ajax4jsf.component.AjaxViewRoot.processEvents(AjaxViewRoot.java:321)
           at org.ajax4jsf.component.AjaxViewRoot.broadcastEvents(AjaxViewRoot.java:296)
           at org.ajax4jsf.component.AjaxViewRoot.processPhase(AjaxViewRoot.java:253)
           at org.ajax4jsf.component.AjaxViewRoot.processApplication(AjaxViewRoot.java:466)
           at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82)
           at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
           at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
           at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
           at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
           at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
           at org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:40)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:177)
           at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:267)
           at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:380)
           at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:507)
           at org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:56)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:58)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.web.HotDeployFilter.doFilter(HotDeployFilter.java:53)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
           at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
           at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
           at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
           at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
           at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
           at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
           at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
           at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:182)
           at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:432)
           at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
           at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
           at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
           at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
           at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
           at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262)
           at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
           at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
           at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446)
           at java.lang.Thread.run(Unknown Source)
      Caused by: javax.ejb.EJBTransactionRolledbackException: Could not create account
           at org.jboss.ejb3.tx.Ejb3TxPolicy.handleInCallerTx(Ejb3TxPolicy.java:87)
           at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:130)
           at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:195)
           at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
           at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:95)
           at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
           at org.jboss.ejb3.stateful.StatefulInstanceInterceptor.invoke(StatefulInstanceInterceptor.java:83)
           at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
           at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
           at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:110)
           at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
           at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46)
           at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
           at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
           at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
           at org.jboss.ejb3.stateful.StatefulContainer.localInvoke(StatefulContainer.java:206)
           at org.jboss.ejb3.stateful.StatefulLocalProxy.invoke(StatefulLocalProxy.java:119)
           at $Proxy122.register(Unknown Source)
           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
           at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
           at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
           at java.lang.reflect.Method.invoke(Unknown Source)
           at org.jboss.seam.util.Reflections.invoke(Reflections.java:22)
           at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:31)
           at org.jboss.seam.intercept.ClientSideInterceptor$1.proceed(ClientSideInterceptor.java:76)
           at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56)
           at org.jboss.seam.ejb.RemoveInterceptor.aroundInvoke(RemoveInterceptor.java:43)
           at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
           at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107)
           at org.jboss.seam.intercept.ClientSideInterceptor.invoke(ClientSideInterceptor.java:54)
           at org.javassist.tmp.java.lang.Object_$$_javassist_1.register(Object_$$_javassist_1.java)
           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
           at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
           at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
           at java.lang.reflect.Method.invoke(Unknown Source)
           at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:329)
           at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:342)
           at org.jboss.el.parser.AstPropertySuffix.invoke(AstPropertySuffix.java:58)
           at org.jboss.el.parser.AstValue.invoke(AstValue.java:96)
           at org.jboss.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
           at com.sun.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:68)
           at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
           ... 51 more
      Caused by: org.jboss.seam.security.management.IdentityManagementException: Could not create account
           at org.jboss.seam.security.management.JpaIdentityStore.createUser(JpaIdentityStore.java:241)
           at org.jboss.seam.security.management.IdentityManager.createUser(IdentityManager.java:100)
           at org.jboss.seam.security.management.IdentityManager.createUser(IdentityManager.java:94)
           at ...session.user.RegisterAction$1.execute(RegisterAction.java:97)
           at org.jboss.seam.security.Identity.runAs(Identity.java:743)
           at org.jboss.seam.security.RunAsOperation.run(RunAsOperation.java:75)
           at ...session.user.RegisterAction.register(RegisterAction.java:104)
           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
           at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
           at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
           at java.lang.reflect.Method.invoke(Unknown Source)
           at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112)
           at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
           at org.jboss.seam.intercept.EJBInvocationContext.proceed(EJBInvocationContext.java:44)
           at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56)
           at org.jboss.seam.transaction.RollbackInterceptor.aroundInvoke(RollbackInterceptor.java:28)
           at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
           at org.jboss.seam.core.BijectionInterceptor.aroundInvoke(BijectionInterceptor.java:77)
           at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
           at org.jboss.seam.core.ConversationInterceptor.aroundInvoke(ConversationInterceptor.java:56)
           at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
           at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:44)
           at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
           at org.jboss.seam.persistence.EntityManagerProxyInterceptor.aroundInvoke(EntityManagerProxyInterceptor.java:29)
           at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
           at org.jboss.seam.persistence.HibernateSessionProxyInterceptor.aroundInvoke(HibernateSessionProxyInterceptor.java:31)
           at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
           at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107)
           at org.jboss.seam.intercept.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:50)
           at sun.reflect.GeneratedMethodAccessor97.invoke(Unknown Source)
           at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
           at java.lang.reflect.Method.invoke(Unknown Source)
           at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:118)
           at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
           at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
           at org.jboss.ejb3.entity.ExtendedPersistenceContextPropagationInterceptor.invoke(ExtendedPersistenceContextPropagationInterceptor.java:57)
           at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
           at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
           at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
           at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
           at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
           at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:126)
           ... 91 more
      Caused by: javax.persistence.NonUniqueResultException: result returns 2 elements
           at org.hibernate.ejb.QueryImpl.getSingleResult(QueryImpl.java:85)
           at org.jboss.seam.security.management.JpaIdentityStore.lookupUser(JpaIdentityStore.java:796)
           at org.jboss.seam.security.management.JpaIdentityStore.userExists(JpaIdentityStore.java:614)
           at org.jboss.seam.security.management.JpaIdentityStore.createUser(JpaIdentityStore.java:203)
           ... 132 more
      19:05:44,691 WARN  [lifecycle] #{register.register}: javax.ejb.EJBTransactionRolledbackException: Could not create account
      // stacktrace again ...
      19:05:44,693 ERROR [lifecycle] JSF1054: (Phase ID: INVOKE_APPLICATION 5, View ID: /user/register.xhtml) Exception thrown during phase execution: javax.faces.event.PhaseEvent[source=com.sun.faces.lifecycle.LifecycleImpl@ef2ab5]
      19:05:44,698 WARN  [ExceptionFilter] handling uncaught exception
      // stacktrace again ...
      19:05:44,699 WARN  [ExceptionFilter] exception root cause
      // stacktrace again ...
      


        • 1. Re: identity manager - duplicate identity created on new user creation with runasoperation
          Julien Kronegg Novice

          According to the exception message, you have two users with username michael in the database.

          • 2. Re: identity manager - duplicate identity created on new user creation with runasoperation
            Michael Pöhlmann Newbie

            Hi Julien,


            thanks for your time looking at my problem. You are right michael would be the second time inserted in the database. But actually before clicking on register the database has been completely empty. I did a little modifications to my code. Here the results:


            changes to RegisterAction


                @End
                public void register() {
                     log.info("register.register() action called for #0", username);
                     if (password == null || !password.equals(verify)) {
                           facesMessages.add("Passwords do not match");
                        facesMessages.addToControl("verify", "Re-enter your password");
                        verify = null;
                        return;
                     }
                     siteUser.setRegistrationDate(new Date());
                     siteUser.setActivationcode(getNewActivationcode());
                     // reactivated, because identityuser could not get an id for siteuser
                     em.persist(siteUser);
                     
                     new RunAsOperation() {
                          @Override
                          public void execute() {
                              log.info("registering new user #0", username);
                              if (identityManager.createUser(username, password)) {
                                   // TODO-Initialrolle
                                   //identityManager.grantRole(username, "user");
                              } else {
                                   facesMessages.add("Registering user #0 failed", username);
                              }
                          }
                     }.addRole("admin").run();
                     log.info("identityuser_id after creation is #0 with siteuser.email #1", identityUser.getId(), identityUser.getSiteUser().getEmail());
                     
                     identityUser.setSiteUser(siteUser);
                     //identityUser = em.merge(identityUser); // creates a second identityuser!!!
                     log.info("identityuser_id after merge for siteuser is #0 with siteuser.email #1", identityUser.getId(), identityUser.getSiteUser().getEmail());
                     
                     registered = true;
                     
                     facesMessages.add("User #{identityuser.username} successfully registered");
                     renderer.render("/user/registrationMail.xhtml");
                }
            



            And now it works!
            Thanks to all readers.


            Michael