1 Reply Latest reply on May 11, 2015 3:15 PM by noamichael

    Problems Creating Custom Group with Child Reference

    noamichael

      Hey guys,

       

      Today, I'm writing a tool in my application to allow users to create their own groups. The tool must be a page with a tree structure which allows the users to create a group, and then add child groups.

       

      I'm thinking the page would be laid out with each group being its own table, and child groups would be sub tables within that:

       

      Staff Group

      Name: [input] (name of group)

      Permissions: [checkboxes] (permissions of the group)

      Add Child Group: [button] (button to add another child group)

       

      Children:
      Manager Group

      Name: [input]

      Permissions: [checkboxes]

      Add Child Group: [button]

      Children:

       

      Product Manager Group

      Name: [input]

      Permissions: [checkboxes]

      Add Child Group: [button]

      Children:[]

      User Group

      Name: [input]

      Permissions: [checkboxes]

      Add Child Group: [button]

      Children:[]

       

       

      From the default model, a Group only has a reference to it's parent, so I extended the group entity to add a list of children so that I could easily build this structure:

       

      public class PlatformGroup extends Group {
      
          @AttributeProperty
          private List<PlatformGroup> children; = new ArrayList<>();
      
          public PlatformGroup() {
      
          }
      
          public PlatformGroup(String name) {
              super(name);
          }
      
          public PlatformGroup(String name, PlatformGroup parentGroup) {
              super(name, parentGroup);
              parentGroup.getChildren().add(this);
          }
      
          /**
           * @return the children
           */
          public List<PlatformGroup> getChildren() {
              return children;
          }
      
          /**
           * @param children the children to set
           */
          public void setChildren(List<PlatformGroup> children) {
              this.children = children;
          }
      }
      
      

       

      ...and the entity:

       

      @Entity
      @IdentityManaged({PlatformGroup.class})
      @XmlRootElement
      public class PlatformGroupEntity extends GroupTypeEntity {
      
          @OneToMany(mappedBy = "parent")
          @AttributeValue
          private List<PlatformGroupEntity> children;
      
          /**
           * @return the children
           */
          public List<PlatformGroupEntity> getChildren() {
              return children;
          }
      
          /**
           * @param children the children to set
           */
          public void setChildren(List<PlatformGroupEntity> children) {
              this.children = children;
          }
      }
      
      

       

       

      However, when I go to run my project, I get the following exception:

       

      Severe:   Exception while loading the app : javax.ejb.CreateException: Initialization failed for Singleton IDMInitializer
      javax.ejb.CreateException: Initialization failed for Singleton IDMInitializer
          at com.sun.ejb.containers.AbstractSingletonContainer.createSingletonEJB(AbstractSingletonContainer.java:476)
          at com.sun.ejb.containers.AbstractSingletonContainer.access$000(AbstractSingletonContainer.java:74)
          at com.sun.ejb.containers.AbstractSingletonContainer$SingletonContextFactory.create(AbstractSingletonContainer.java:647)
          at com.sun.ejb.containers.AbstractSingletonContainer.instantiateSingletonInstance(AbstractSingletonContainer.java:389)
          at org.glassfish.ejb.startup.SingletonLifeCycleManager.initializeSingleton(SingletonLifeCycleManager.java:219)
          at org.glassfish.ejb.startup.SingletonLifeCycleManager.initializeSingleton(SingletonLifeCycleManager.java:180)
          at org.glassfish.ejb.startup.SingletonLifeCycleManager.doStartup(SingletonLifeCycleManager.java:158)
          at org.glassfish.ejb.startup.EjbApplication.start(EjbApplication.java:166)
          at org.glassfish.internal.data.EngineRef.start(EngineRef.java:122)
          at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:291)
          at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:352)
          at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:500)
          at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:219)
          at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:491)
          at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:539)
          at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:535)
          at java.security.AccessController.doPrivileged(Native Method)
          at javax.security.auth.Subject.doAs(Subject.java:360)
          at com.sun.enterprise.v3.admin.CommandRunnerImpl$2.execute(CommandRunnerImpl.java:534)
          at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:565)
          at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:557)
          at java.security.AccessController.doPrivileged(Native Method)
          at javax.security.auth.Subject.doAs(Subject.java:360)
          at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:556)
          at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1464)
          at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1300(CommandRunnerImpl.java:109)
          at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1846)
          at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1722)
          at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:534)
          at com.sun.enterprise.v3.admin.AdminAdapter.onMissingResource(AdminAdapter.java:224)
          at org.glassfish.grizzly.http.server.StaticHttpHandlerBase.service(StaticHttpHandlerBase.java:189)
          at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
          at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
          at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201)
          at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175)
          at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
          at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
          at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
          at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
          at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
          at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
          at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
          at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
          at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
          at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
          at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
          at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
          at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
          at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
          at java.lang.Thread.run(Thread.java:745)
      Caused by: org.picketlink.idm.IdentityManagementException: PLIDM000501: Could not query IdentityType using query [org.picketlink.idm.query.internal.DefaultIdentityQuery@2194c07d].
          at org.picketlink.idm.query.internal.DefaultIdentityQuery.getResultList(DefaultIdentityQuery.java:200)
          at org.picketlink.idm.internal.ContextualIdentityManager.checkUniqueness(ContextualIdentityManager.java:319)
          at org.picketlink.idm.internal.ContextualIdentityManager.add(ContextualIdentityManager.java:90)
          at org.noamichael.picketlink.impl.InitializeSecurityDefault.createGroups(InitializeSecurityDefault.java:80)
          at org.noamichael.picketlink.impl.InitializeSecurityDefault.initializeSecurity(InitializeSecurityDefault.java:54)
          at org.noamichael.picketlink.impl.InitializeSecurityDefault$Proxy$_$$_WeldClientProxy.initializeSecurity(Unknown Source)
          at org.noamichael.picketlink.config.IDMInitializer.create(IDMInitializer.java:39)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
          at java.lang.reflect.Method.invoke(Method.java:483)
          at com.sun.ejb.containers.interceptors.BeanCallbackInterceptor.intercept(InterceptorManager.java:1035)
          at com.sun.ejb.containers.interceptors.CallbackChainImpl.invokeNext(CallbackChainImpl.java:72)
          at com.sun.ejb.containers.interceptors.CallbackInvocationContext.proceed(CallbackInvocationContext.java:205)
          at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:55)
          at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:52)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
          at java.lang.reflect.Method.invoke(Method.java:483)
          at com.sun.ejb.containers.interceptors.CallbackInterceptor.intercept(InterceptorManager.java:986)
          at com.sun.ejb.containers.interceptors.CallbackChainImpl.invokeNext(CallbackChainImpl.java:72)
          at com.sun.ejb.containers.interceptors.CallbackInvocationContext.proceed(CallbackInvocationContext.java:205)
          at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doCall(SystemInterceptorProxy.java:163)
          at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.init(SystemInterceptorProxy.java:125)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
          at java.lang.reflect.Method.invoke(Method.java:483)
          at com.sun.ejb.containers.interceptors.CallbackInterceptor.intercept(InterceptorManager.java:986)
          at com.sun.ejb.containers.interceptors.CallbackChainImpl.invokeNext(CallbackChainImpl.java:72)
          at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:412)
          at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:375)
          at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:2014)
          at com.sun.ejb.containers.AbstractSingletonContainer.createSingletonEJB(AbstractSingletonContainer.java:468)
          ... 49 more
      Caused by: javax.persistence.PersistenceException: java.lang.NullPointerException
          at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:480)
          at org.picketlink.idm.jpa.internal.JPAIdentityStore.fetchQueryResults(JPAIdentityStore.java:558)
          at org.picketlink.idm.query.internal.DefaultIdentityQuery.getResultList(DefaultIdentityQuery.java:189)
          ... 83 more
      Caused by: java.lang.NullPointerException
          at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.checkForUnregisteredExistingObject(UnitOfWorkImpl.java:773)
          at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.discoverAndPersistUnregisteredNewObjects(UnitOfWorkImpl.java:4194)
          at org.eclipse.persistence.mappings.CollectionMapping.cascadeDiscoverAndPersistUnregisteredNewObjects(CollectionMapping.java:483)
          at org.eclipse.persistence.internal.descriptors.ObjectBuilder.cascadeDiscoverAndPersistUnregisteredNewObjects(ObjectBuilder.java:2514)
          at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.discoverAndPersistUnregisteredNewObjects(UnitOfWorkImpl.java:4207)
          at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.discoverUnregisteredNewObjects(RepeatableWriteUnitOfWork.java:305)
          at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.calculateChanges(UnitOfWorkImpl.java:723)
          at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.writeChanges(RepeatableWriteUnitOfWork.java:438)
          at org.eclipse.persistence.internal.jpa.EntityManagerImpl.flush(EntityManagerImpl.java:863)
          at org.eclipse.persistence.internal.jpa.QueryImpl.performPreQueryFlush(QueryImpl.java:963)
          at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:207)
          at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:469)
          ... 85 more
      
      

       

       

      Is this type of mapping not supported by Picketlink? I can see that eclipselink is checking for unregistered objects and experiencing a null pointer exception. My guess is that when I go to add the parent group, the child group has not yet been added using identityManager.add. Any ideas for a possible solution? I need this kind of tree structure in order to build the maintenance tool as per company requirements.

        • 1. Re: Problems Creating Custom Group with Child Reference
          noamichael

          I have a temporary solution to this problem:

           

          I can iterate though all of the found groups from a given query, and recreate the tree structure.

           

           

          public static List<PlatformGroup> createTreeStructure(List<PlatformGroup> groups) {
                  //Single group instances - only one reference
                  Map<String, PlatformGroup> groupToId = new HashMap();
                  //map id to group
                  groups.forEach(g -> groupToId.put(g.getId(), g));
                  //create actually tree structure using map instances
                  groups.stream().forEach(g -> {
                      PlatformGroup parent = (PlatformGroup) g.getParentGroup();
                      if (parent != null) {
                          if(!groupToId.containsKey(parent.getId())){
                              groupToId.put(parent.getId(), parent);
                          }
                          groupToId.get(parent.getId()).getChildren().add(g);
                      }
                  });
                  List<PlatformGroup> withChildren = new ArrayList<>(groupToId.values())
                          .stream().filter(g -> g.getParentGroup() == null)
                          .collect(Collectors.toList());
                  return withChildren;
              }
          

           

           

          This will return a list of only the top level groups who have no parents (root groups). The children can then be found by calling group.getChildren. This works, but I have to ensure that every set of group query results first get past through this method. Still looking for better solution.