/**
   * 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;
    }
  }
 private void createEntityValuesResponseRec(
     Entity entity,
     Iterable<AttributeMetaData> attrs,
     Fetch fetch,
     Map<String, Object> responseData) {
   responseData.put(
       "_href",
       Href.concatEntityHref(BASE_URI, entity.getEntityMetaData().getName(), entity.getIdValue()));
   for (AttributeMetaData attr : attrs) // TODO performance use fetch instead of attrs
   {
     String attrName = attr.getName();
     if (fetch == null || fetch.hasField(attr)) {
       FieldTypeEnum dataType = attr.getDataType().getEnumType();
       switch (dataType) {
         case BOOL:
           responseData.put(attrName, entity.getBoolean(attrName));
           break;
         case CATEGORICAL:
         case XREF:
         case FILE:
           Entity refEntity = entity.getEntity(attrName);
           Map<String, Object> refEntityResponse;
           if (refEntity != null) {
             Fetch refAttrFetch = fetch != null ? fetch.getFetch(attr) : null;
             refEntityResponse = createEntityResponse(refEntity, refAttrFetch, false);
           } else {
             refEntityResponse = null;
           }
           responseData.put(attrName, refEntityResponse);
           break;
         case CATEGORICAL_MREF:
         case MREF:
           Iterable<Entity> refEntities = entity.getEntities(attrName);
           List<Map<String, Object>> refEntityResponses;
           if (refEntities != null) {
             refEntityResponses = new ArrayList<Map<String, Object>>();
             Fetch refAttrFetch = fetch != null ? fetch.getFetch(attrName) : null;
             for (Entity refEntitiesEntity : refEntities) {
               refEntityResponses.add(
                   createEntityResponse(refEntitiesEntity, refAttrFetch, false));
             }
           } else {
             refEntityResponses = null;
           }
           responseData.put(attrName, refEntityResponses);
           break;
         case COMPOUND:
           throw new RuntimeException("Invalid data type [" + dataType + "]");
         case DATE:
           Date dateValue = entity.getDate(attrName);
           String dateValueStr = dateValue != null ? getDateFormat().format(dateValue) : null;
           responseData.put(attrName, dateValueStr);
           break;
         case DATE_TIME:
           Date dateTimeValue = entity.getDate(attrName);
           String dateTimeValueStr =
               dateTimeValue != null ? getDateTimeFormat().format(dateTimeValue) : null;
           responseData.put(attrName, dateTimeValueStr);
           break;
         case DECIMAL:
           responseData.put(attrName, entity.getDouble(attrName));
           break;
         case EMAIL:
         case ENUM:
         case HTML:
         case HYPERLINK:
         case SCRIPT:
         case STRING:
         case TEXT:
           responseData.put(attrName, entity.getString(attrName));
           break;
         case INT:
           responseData.put(attrName, entity.getInt(attrName));
           break;
         case LONG:
           responseData.put(attrName, entity.getLong(attrName));
           break;
         default:
           throw new RuntimeException("Unknown data type [" + dataType + "]");
       }
     }
   }
 }