How to restrict the single root node in Access Group

Hi,
I am creating an application, where i want to restrict the user to create one single root node in access group. Now in the Access Group hierarchy, it has a possible of creating multiple root nodes. So, plz suggest me how to accomplish this…
Thank you…

Hi Vimal,
Usually such tasks are performed by Entity Listeners. In your case, the problem is a bit more complicated, because you need an entity listener for the entity not belonging to your project - Group, which is provided by the platform.
So, when creating the listener in Studio, keep the Use for entities list empty:
image

To register the listener for the Group entity, make it also a listener of the AppContextInitializedEvent lifecycle event and register it in the EntityListenerManager. In the onBeforeInsert/onBeforeUpdate methods, check if a root group is already present and throw an exception. If you want to show a nice notification to users, create your own exception class and use Client-Level Exception Handlers to display an appropriate message.

package com.company.playground.listener;

import com.haulmont.cuba.core.EntityManager;
import com.haulmont.cuba.core.global.Events;
import com.haulmont.cuba.core.listener.BeforeInsertEntityListener;
import com.haulmont.cuba.core.listener.BeforeUpdateEntityListener;
import com.haulmont.cuba.core.sys.events.AppContextInitializedEvent;
import com.haulmont.cuba.core.sys.listener.EntityListenerManager;
import com.haulmont.cuba.security.entity.Group;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.inject.Inject;
import java.util.List;

@Component("playground_MyGroupEntityListener")
public class MyGroupEntityListener implements BeforeInsertEntityListener<Group>, BeforeUpdateEntityListener<Group> {

    @Inject
    private EntityListenerManager entityListenerManager;

    @EventListener(AppContextInitializedEvent.class) // notify after AppContext is initialized
    @Order(Events.LOWEST_PLATFORM_PRECEDENCE + 100)  // run after all platform listeners
    public void initEntityListeners() {
        entityListenerManager.addListener(Group.class, "playground_MyGroupEntityListener");
    }

    @Override
    public void onBeforeInsert(Group entity, EntityManager entityManager) {
        checkRootItemExists(entity, entityManager);
    }

    @Override
    public void onBeforeUpdate(Group entity, EntityManager entityManager) {
        checkRootItemExists(entity, entityManager);
    }

    private void checkRootItemExists(Group group, EntityManager entityManager) {
        if (group.getParent() != null)
            return;

        List<Group> list = entityManager.createQuery(
                "select g from sec$Group g where g.parent is null", Group.class).getResultList();
        if (!list.isEmpty() && !list.get(0).equals(group)) {
            throw new RuntimeException("A root group already exists");
        }
    }
}