@Transactional
 public AccessKey create(@NotNull User user, @NotNull AccessKey accessKey) {
   if (accessKey.getLabel() == null) {
     throw new IllegalParametersException(Messages.LABEL_IS_REQUIRED);
   }
   Optional<AccessKey> akOpt =
       genericDAO
           .createNamedQuery(
               AccessKey.class, "AccessKey.getByUserAndLabel", Optional.<CacheConfig>empty())
           .setParameter("userId", user.getId())
           .setParameter("label", accessKey.getLabel())
           .getResultList()
           .stream()
           .findFirst();
   if (akOpt.isPresent()) {
     logger.error("Access key with label {} already exists", accessKey.getLabel());
     throw new ActionNotAllowedException(Messages.DUPLICATE_LABEL_FOUND);
   }
   if (accessKey.getId() != null) {
     logger.error("Access key id shouldn't be present in request parameters");
     throw new IllegalParametersException(Messages.INVALID_REQUEST_PARAMETERS);
   }
   authenticationUtils.validateActions(accessKey);
   AccessKeyProcessor keyProcessor = new AccessKeyProcessor();
   String key = keyProcessor.generateKey();
   accessKey.setKey(key);
   accessKey.setUser(user);
   genericDAO.persist(accessKey);
   for (AccessKeyPermission current : accessKey.getPermissions()) {
     AccessKeyPermission permission = preparePermission(current);
     permission.setAccessKey(accessKey);
     genericDAO.persist(permission);
   }
   return genericDAO.find(AccessKey.class, accessKey.getId());
 }
  @Transactional(propagation = Propagation.REQUIRED)
  public AccessKey authenticate(@NotNull User user) {
    userService.refreshUserLoginData(user);

    AccessKey accessKey = authenticationUtils.prepareAccessKey(user);

    Set<AccessKeyPermission> permissions = new HashSet<>();
    final AccessKeyPermission permission = authenticationUtils.preparePermission(user.getRole());
    permissions.add(permission);
    accessKey.setPermissions(permissions);
    genericDAO.persist(accessKey);

    permission.setAccessKey(accessKey);
    genericDAO.persist(permission);
    return accessKey;
  }
  @Transactional
  public boolean update(@NotNull Long userId, @NotNull Long keyId, AccessKeyUpdate toUpdate) {
    AccessKey existing = find(keyId, userId);
    if (existing == null) {
      return false;
    }
    if (toUpdate == null) {
      return true;
    }

    if (toUpdate.getLabel() != null) {
      existing.setLabel(toUpdate.getLabel().orElse(null));
    }
    if (toUpdate.getExpirationDate() != null) {
      existing.setExpirationDate(toUpdate.getExpirationDate().orElse(null));
    }
    if (toUpdate.getType() != null) {
      existing.setType(toUpdate.getType().map(v -> toUpdate.getTypeEnum()).orElse(null));
    }
    if (toUpdate.getPermissions() != null) {
      if (!toUpdate.getPermissions().isPresent()) {
        logger.error("New permissions shouldn't be empty in request parameters");
        throw new IllegalParametersException(Messages.INVALID_REQUEST_PARAMETERS);
      }

      Set<AccessKeyPermission> permissionsToReplace = toUpdate.getPermissions().get();
      AccessKey toValidate = toUpdate.convertTo();
      authenticationUtils.validateActions(toValidate);
      deleteAccessKeyPermissions(existing);
      for (AccessKeyPermission current : permissionsToReplace) {
        AccessKeyPermission permission = preparePermission(current);
        permission.setAccessKey(existing);
        genericDAO.persist(permission);
      }
    }
    return true;
  }