@Override
  public Repository createDecoratedRepository(Repository repository) {
    Repository decoratedRepository = repositoryDecoratorRegistry.decorate(repository);

    if (decoratedRepository.getName().equals(MolgenisUserMetaData.ENTITY_NAME)) {
      decoratedRepository = new MolgenisUserDecorator(decoratedRepository);
    }

    // 9. Owned decorator
    if (EntityUtils.doesExtend(
        decoratedRepository.getEntityMetaData(), OwnedEntityMetaData.ENTITY_NAME)) {
      decoratedRepository = new OwnedEntityRepositoryDecorator(decoratedRepository);
    }

    // 8. Entity reference resolver decorator
    decoratedRepository = new EntityReferenceResolverDecorator(decoratedRepository, entityManager);

    // 7. Computed entity values decorator
    decoratedRepository = new ComputedEntityValuesDecorator(decoratedRepository);

    // 6. Entity listener
    decoratedRepository = new EntityListenerRepositoryDecorator(decoratedRepository);

    // 5. Transaction log decorator
    decoratedRepository =
        new TransactionLogRepositoryDecorator(decoratedRepository, transactionLogService);

    // 4. SQL exception translation decorator
    String backend = decoratedRepository.getEntityMetaData().getBackend();
    if (MysqlRepositoryCollection.NAME.equals(backend)) {
      decoratedRepository = new MySqlRepositoryExceptionTranslatorDecorator(decoratedRepository);
    }

    // 3. validation decorator
    decoratedRepository =
        new RepositoryValidationDecorator(
            dataService, decoratedRepository, entityAttributesValidator, expressionValidator);

    // 2. auto value decorator
    decoratedRepository = new AutoValueRepositoryDecorator(decoratedRepository, idGenerator);

    // 1. security decorator
    decoratedRepository = new RepositorySecurityDecorator(decoratedRepository, appSettings);

    return decoratedRepository;
  }
  private void validateEntityValueRequired(Entity entity, ValidationResource validationResource) {
    validationResource
        .getRequiredValueAttrs()
        .forEach(
            nonNillableAttr -> {
              Object value = entity.get(nonNillableAttr.getName());
              if (value == null
                  || (nonNillableAttr.getDataType() instanceof MrefField
                      && !entity.getEntities(nonNillableAttr.getName()).iterator().hasNext())) {
                boolean isValid = false;

                // FIXME remove hack (see https://github.com/molgenis/molgenis/issues/4308)
                // Do not validate if Questionnaire status is not SUBMITTED
                if (EntityUtils.doesExtend(getEntityMetaData(), "Questionnaire")
                    && !"SUBMITTED".equals(entity.getString("status"))) {
                  isValid = true;
                }
                // Do not validate if visibleExpression resolves to false
                else if (nonNillableAttr.getVisibleExpression() != null
                    && !expressionValidator.resolveBooleanExpression(
                        nonNillableAttr.getVisibleExpression(), entity, getEntityMetaData())) {

                  isValid = true;
                }

                if (!isValid) {
                  String message =
                      format(
                          "The attribute '%s' of entity '%s' can not be null.",
                          nonNillableAttr.getName(), getName());

                  ConstraintViolation constraintViolation =
                      new ConstraintViolation(
                          message, nonNillableAttr, Long.valueOf(validationResource.getRow()));
                  validationResource.addViolation(constraintViolation);
                }
              }
            });
  }
 private boolean hasValues(Entity e) {
   return !EntityUtils.isEmpty(e);
 }