@Override
  @Transactional
  public void save(ResourceEntity entity, final String requestorId) {
    if (entity.getResourceType() != null) {
      entity.setResourceType(resourceTypeDao.findById(entity.getResourceType().getId()));
    }

    /* admin resource can't have an admin resource - do this check here */
    boolean isAdminResource =
        StringUtils.equals(entity.getResourceType().getId(), adminResourceTypeId);

    if (entity.getType() != null && StringUtils.isNotBlank(entity.getType().getId())) {
      entity.setType(typeDAO.findById(entity.getType().getId()));
    } else {
      entity.setType(null);
    }

    if (StringUtils.isNotBlank(entity.getId())) {
      final ResourceEntity dbObject = resourceDao.findById(entity.getId());
      entity.setAdminResource(dbObject.getAdminResource());
      entity.setApproverAssociations(dbObject.getApproverAssociations());

      if (isAdminResource) {
        entity.setAdminResource(null);
      } else if (entity.getAdminResource() == null) {
        final ResourceEntity adminResource = getNewAdminResource(entity, requestorId);
        entity.setAdminResource(adminResource);
        if (CollectionUtils.isEmpty(dbObject.getApproverAssociations())) {
          entity.addApproverAssociation(createDefaultApproverAssociations(entity, requestorId));
        }
      }
      entity.setChildResources(dbObject.getChildResources());
      entity.setParentResources(dbObject.getParentResources());
      entity.setUsers(dbObject.getUsers());
      entity.setGroups(dbObject.getGroups());
      entity.setRoles(dbObject.getRoles());

      // elementDAO.flush();
      mergeAttribute(entity, dbObject);

    } else {
      boolean addApproverAssociation = false;
      if (isAdminResource) {
        entity.setAdminResource(null);
      } else {
        entity.setAdminResource(getNewAdminResource(entity, requestorId));
        addApproverAssociation = true;
      }
      resourceDao.save(entity);

      if (addApproverAssociation) {
        entity.addApproverAssociation(createDefaultApproverAssociations(entity, requestorId));
      }

      addRequiredAttributes(entity);
    }

    resourceDao.merge(entity);
  }
 private boolean causesCircularDependency(
     final ResourceEntity parent,
     final ResourceEntity child,
     final Set<ResourceEntity> visitedSet) {
   boolean retval = false;
   if (parent != null && child != null) {
     if (!visitedSet.contains(child)) {
       visitedSet.add(child);
       if (CollectionUtils.isNotEmpty(parent.getParentResources())) {
         for (final ResourceEntity entity : parent.getParentResources()) {
           retval = entity.getId().equals(child.getId());
           if (retval) {
             break;
           }
           causesCircularDependency(parent, entity, visitedSet);
         }
       }
     }
   }
   return retval;
 }