/**
   * @param entityName The name of the entity to update
   * @param attributeName The name of the attribute to update
   * @param request EntityCollectionBatchRequestV2
   * @param response HttpServletResponse
   * @throws Exception
   */
  @RequestMapping(value = "/{entityName}/{attributeName}", method = PUT)
  @ResponseStatus(OK)
  public synchronized void updateAttribute(
      @PathVariable("entityName") String entityName,
      @PathVariable("attributeName") String attributeName,
      @RequestBody @Valid EntityCollectionBatchRequestV2 request,
      HttpServletResponse response)
      throws Exception {
    final EntityMetaData meta = dataService.getEntityMetaData(entityName);
    if (meta == null) {
      throw createUnknownEntityException(entityName);
    }

    try {
      AttributeMetaData attr = meta.getAttribute(attributeName);
      if (attr == null) {
        throw createUnknownAttributeException(entityName, attributeName);
      }

      if (attr.isReadonly()) {
        throw createMolgenisDataAccessExceptionReadOnlyAttribute(entityName, attributeName);
      }

      final List<Entity> entities =
          request
              .getEntities()
              .stream()
              .filter(e -> e.size() == 2)
              .map(e -> this.restService.toEntity(meta, e))
              .collect(Collectors.toList());
      if (entities.size() != request.getEntities().size()) {
        throw createMolgenisDataExceptionIdentifierAndValue();
      }

      final List<Entity> updatedEntities = new ArrayList<Entity>();
      int count = 0;
      for (Entity entity : entities) {
        String id = checkForEntityId(entity, count);

        Entity originalEntity = dataService.findOne(entityName, id);
        if (originalEntity == null) {
          throw createUnknownEntityExceptionNotValidId(id);
        }

        Object value = this.restService.toEntityValue(attr, entity.get(attributeName));
        originalEntity.set(attributeName, value);
        updatedEntities.add(originalEntity);
        count++;
      }

      // update all entities
      this.dataService.update(entityName, updatedEntities.stream());
      response.setStatus(HttpServletResponse.SC_OK);
    } catch (Exception e) {
      response.setStatus(HttpServletResponse.SC_NO_CONTENT);
      throw e;
    }
  }
  /**
   * Try to create multiple entities in one transaction. If one fails all fails.
   *
   * @param entityName name of the entity where the entities are going to be added.
   * @param request EntityCollectionCreateRequestV2
   * @param response HttpServletResponse
   * @return EntityCollectionCreateResponseBodyV2
   * @throws Exception
   */
  @RequestMapping(value = "/{entityName}", method = POST, produces = APPLICATION_JSON_VALUE)
  @ResponseBody
  public EntityCollectionBatchCreateResponseBodyV2 createEntities(
      @PathVariable("entityName") String entityName,
      @RequestBody @Valid EntityCollectionBatchRequestV2 request,
      HttpServletResponse response)
      throws Exception {
    final EntityMetaData meta = dataService.getEntityMetaData(entityName);
    if (meta == null) {
      throw createUnknownEntityException(entityName);
    }

    try {
      final List<Entity> entities =
          request
              .getEntities()
              .stream()
              .map(e -> this.restService.toEntity(meta, e))
              .collect(Collectors.toList());
      final EntityCollectionBatchCreateResponseBodyV2 responseBody =
          new EntityCollectionBatchCreateResponseBodyV2();
      final List<String> ids = new ArrayList<String>();

      // Add all entities
      this.dataService.add(entityName, entities.stream());

      entities.forEach(
          entity -> {
            String id = entity.getIdValue().toString();
            ids.add(id.toString());
            responseBody
                .getResources()
                .add(
                    new AutoValue_ResourcesResponseV2(
                        Href.concatEntityHref(RestControllerV2.BASE_URI, entityName, id)));
          });

      responseBody.setLocation(
          Href.concatEntityCollectionHref(
              RestControllerV2.BASE_URI, entityName, meta.getIdAttribute().getName(), ids));

      response.setStatus(HttpServletResponse.SC_CREATED);
      return responseBody;
    } catch (Exception e) {
      response.setStatus(HttpServletResponse.SC_NO_CONTENT);
      throw e;
    }
  }
  /**
   * Try to update multiple entities in one transaction. If one fails all fails.
   *
   * @param entityName name of the entity where the entities are going to be added.
   * @param request EntityCollectionCreateRequestV2
   * @param response HttpServletResponse
   * @throws Exception
   */
  @RequestMapping(value = "/{entityName}", method = PUT)
  public synchronized void updateEntities(
      @PathVariable("entityName") String entityName,
      @RequestBody @Valid EntityCollectionBatchRequestV2 request,
      HttpServletResponse response)
      throws Exception {
    final EntityMetaData meta = dataService.getEntityMetaData(entityName);
    if (meta == null) {
      throw createUnknownEntityException(entityName);
    }

    try {
      final Stream<Entity> entities =
          request.getEntities().stream().map(e -> this.restService.toEntity(meta, e));

      // update all entities
      this.dataService.update(entityName, entities);
      response.setStatus(HttpServletResponse.SC_OK);
    } catch (Exception e) {
      response.setStatus(HttpServletResponse.SC_NO_CONTENT);
      throw e;
    }
  }