Search in sources :

Example 6 with ConstraintViolation

use of org.molgenis.data.validation.ConstraintViolation in project molgenis by molgenis.

the class PostgreSqlExceptionTranslator method translateNotNullViolation.

/**
 * Package private for testability
 *
 * @param pSqlException PostgreSQL exception
 * @return translated validation exception
 */
MolgenisValidationException translateNotNullViolation(PSQLException pSqlException) {
    ServerErrorMessage serverErrorMessage = pSqlException.getServerErrorMessage();
    String tableName = serverErrorMessage.getTable();
    String message = serverErrorMessage.getMessage();
    Matcher matcher = Pattern.compile("null value in column \"?(.*?)\"? violates not-null constraint").matcher(message);
    boolean matches = matcher.matches();
    if (matches) {
        // exception message when adding data that does not match constraint
        String columnName = matcher.group(1);
        EntityTypeDescription entityTypeDescription = entityTypeRegistry.getEntityTypeDescription(tableName);
        entityTypeDescription.getAttributeDescriptionMap().get(columnName);
        ConstraintViolation constraintViolation = new ConstraintViolation(format("The attribute '%s' of entity '%s' can not be null.", getAttributeName(tableName, columnName), getEntityTypeName(tableName)), null);
        return new MolgenisValidationException(singleton(constraintViolation));
    } else {
        // exception message when applying constraint on existing data
        matcher = Pattern.compile("column \"(.*?)\" contains null values").matcher(message);
        matches = matcher.matches();
        if (!matches) {
            throw new RuntimeException("Error translating exception", pSqlException);
        }
        String columnName = matcher.group(1);
        ConstraintViolation constraintViolation = new ConstraintViolation(format("The attribute '%s' of entity '%s' contains null values.", getAttributeName(tableName, columnName), getEntityTypeName(tableName)), null);
        return new MolgenisValidationException(singleton(constraintViolation));
    }
}
Also used : Matcher(java.util.regex.Matcher) ServerErrorMessage(org.postgresql.util.ServerErrorMessage) ConstraintViolation(org.molgenis.data.validation.ConstraintViolation) EntityTypeDescription(org.molgenis.data.postgresql.identifier.EntityTypeDescription) MolgenisValidationException(org.molgenis.data.validation.MolgenisValidationException)

Example 7 with ConstraintViolation

use of org.molgenis.data.validation.ConstraintViolation in project molgenis by molgenis.

the class PostgreSqlExceptionTranslator method translateUniqueKeyViolation.

/**
 * Package private for testability
 *
 * @param pSqlException PostgreSQL exception
 * @return translated validation exception
 */
MolgenisValidationException translateUniqueKeyViolation(PSQLException pSqlException) {
    ServerErrorMessage serverErrorMessage = pSqlException.getServerErrorMessage();
    String tableName = serverErrorMessage.getTable();
    String detailMessage = serverErrorMessage.getDetail();
    Matcher matcher = Pattern.compile("Key \\(\"?(.*?)\"?\\)=\\((.*?)\\) already exists.").matcher(detailMessage);
    boolean matches = matcher.matches();
    if (matches) {
        ConstraintViolation constraintViolation;
        // exception message when adding data that does not match constraint
        String[] columnNames = matcher.group(1).split(", ");
        if (columnNames.length == 1) {
            String columnName = columnNames[0];
            String value = matcher.group(2);
            constraintViolation = new ConstraintViolation(format("Duplicate value '%s' for unique attribute '%s' from entity '%s'.", value, getAttributeName(tableName, columnName), getEntityTypeName(tableName)), null);
        } else {
            String columnName = columnNames[columnNames.length - 1];
            String[] values = matcher.group(2).split(", ");
            String idValue = values[0];
            String value = values[1];
            constraintViolation = new ConstraintViolation(format("Duplicate list value '%s' for attribute '%s' from entity '%s' with id '%s'.", value, getAttributeName(tableName, columnName), getEntityTypeName(tableName), idValue), null);
        }
        return new MolgenisValidationException(singleton(constraintViolation));
    } else {
        // exception message when applying constraint on existing data
        matcher = Pattern.compile("Key \\(\"?(.*?)\"?\\)=\\((.*?)\\) is duplicated.").matcher(detailMessage);
        matches = matcher.matches();
        if (matches) {
            String columnName = matcher.group(1);
            String value = matcher.group(2);
            ConstraintViolation constraintViolation = new ConstraintViolation(format("The attribute '%s' of entity '%s' contains duplicate value '%s'.", getAttributeName(tableName, columnName), getEntityTypeName(tableName), value), null);
            return new MolgenisValidationException(singleton(constraintViolation));
        } else {
            LOG.error("Error translating postgres exception: ", pSqlException);
            throw new RuntimeException("Error translating exception", pSqlException);
        }
    }
}
Also used : Matcher(java.util.regex.Matcher) ServerErrorMessage(org.postgresql.util.ServerErrorMessage) ConstraintViolation(org.molgenis.data.validation.ConstraintViolation) MolgenisValidationException(org.molgenis.data.validation.MolgenisValidationException)

Example 8 with ConstraintViolation

use of org.molgenis.data.validation.ConstraintViolation in project molgenis by molgenis.

the class PostgreSqlExceptionTranslator method translateUndefinedColumnException.

/**
 * Package private for testability
 *
 * @param pSqlException PostgreSQL exception
 * @return translated validation exception
 */
static MolgenisValidationException translateUndefinedColumnException(PSQLException pSqlException) {
    ServerErrorMessage serverErrorMessage = pSqlException.getServerErrorMessage();
    // FIXME exposes internal message
    String message = serverErrorMessage.getMessage();
    ConstraintViolation constraintViolation = new ConstraintViolation(message);
    return new MolgenisValidationException(singleton(constraintViolation));
}
Also used : ServerErrorMessage(org.postgresql.util.ServerErrorMessage) ConstraintViolation(org.molgenis.data.validation.ConstraintViolation) MolgenisValidationException(org.molgenis.data.validation.MolgenisValidationException)

Example 9 with ConstraintViolation

use of org.molgenis.data.validation.ConstraintViolation in project molgenis by molgenis.

the class PostgreSqlExceptionTranslator method translateDependentObjectsStillExist.

/**
 * Package private for testability
 *
 * @param pSqlException PostgreSQL exception
 * @return translated validation exception
 */
MolgenisValidationException translateDependentObjectsStillExist(PSQLException pSqlException) {
    ServerErrorMessage serverErrorMessage = pSqlException.getServerErrorMessage();
    String detail = serverErrorMessage.getDetail();
    Matcher matcher = Pattern.compile("constraint (.+) on table \"?([^\"]+)\"? depends on table \"?([^\"]+)\"?\n?").matcher(detail);
    Map<String, Set<String>> entityTypeDependencyMap = new LinkedHashMap<>();
    while (matcher.find()) {
        String tableName = matcher.group(2);
        String dependentTableName = matcher.group(3);
        String entityTypeName = getEntityTypeName(tableName);
        String dependentEntityTypeName = getEntityTypeName(dependentTableName);
        Set<String> dependentTableNames = entityTypeDependencyMap.computeIfAbsent(dependentEntityTypeName, k -> new LinkedHashSet<>());
        dependentTableNames.add(entityTypeName);
    }
    if (// no matches
    entityTypeDependencyMap.isEmpty()) {
        LOG.error("Error translating postgres exception: ", pSqlException);
        throw new RuntimeException("Error translating exception", pSqlException);
    }
    Set<ConstraintViolation> constraintViolations = entityTypeDependencyMap.entrySet().stream().map(entry -> {
        String message;
        if (entry.getValue().size() == 1) {
            message = format("Cannot delete entity '%s' because entity '%s' depends on it.", entry.getKey(), entry.getValue().iterator().next());
        } else {
            message = format("Cannot delete entity '%s' because entities '%s' depend on it.", entry.getKey(), entry.getValue().stream().collect(joining(", ")));
        }
        return new ConstraintViolation(message, null);
    }).collect(toCollection(LinkedHashSet::new));
    return new MolgenisValidationException(constraintViolations);
}
Also used : EntityTypeDescription(org.molgenis.data.postgresql.identifier.EntityTypeDescription) DataAccessException(org.springframework.dao.DataAccessException) BatchUpdateException(java.sql.BatchUpdateException) ConstraintViolation(org.molgenis.data.validation.ConstraintViolation) ServerErrorMessage(org.postgresql.util.ServerErrorMessage) LoggerFactory(org.slf4j.LoggerFactory) PSQLException(org.postgresql.util.PSQLException) LinkedHashMap(java.util.LinkedHashMap) Collectors.toCollection(java.util.stream.Collectors.toCollection) EntityTypeRegistry(org.molgenis.data.postgresql.identifier.EntityTypeRegistry) SQLException(java.sql.SQLException) Matcher(java.util.regex.Matcher) Collections.singleton(java.util.Collections.singleton) Map(java.util.Map) Objects.requireNonNull(java.util.Objects.requireNonNull) DataSource(javax.sql.DataSource) LinkedHashSet(java.util.LinkedHashSet) SQLErrorCodeSQLExceptionTranslator(org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator) TransactionExceptionTranslator(org.molgenis.data.transaction.TransactionExceptionTranslator) AttributeType(org.molgenis.data.meta.AttributeType) Logger(org.slf4j.Logger) MolgenisValidationException(org.molgenis.data.validation.MolgenisValidationException) Set(java.util.Set) String.format(java.lang.String.format) Collectors.joining(java.util.stream.Collectors.joining) Component(org.springframework.stereotype.Component) TransactionException(org.springframework.transaction.TransactionException) Pattern(java.util.regex.Pattern) MolgenisDataException(org.molgenis.data.MolgenisDataException) AttributeDescription(org.molgenis.data.postgresql.identifier.AttributeDescription) LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) Matcher(java.util.regex.Matcher) ServerErrorMessage(org.postgresql.util.ServerErrorMessage) MolgenisValidationException(org.molgenis.data.validation.MolgenisValidationException) LinkedHashMap(java.util.LinkedHashMap) ConstraintViolation(org.molgenis.data.validation.ConstraintViolation)

Example 10 with ConstraintViolation

use of org.molgenis.data.validation.ConstraintViolation in project molgenis by molgenis.

the class PostgreSqlRepository method verifyUpdate.

private void verifyUpdate(List<? extends Entity> entitiesBatch, int[] counts, Attribute idAttr) {
    int nrUpdatedEntities = Arrays.stream(counts).sum();
    if (nrUpdatedEntities < entitiesBatch.size()) {
        Set<Object> existingEntityIds = findAll(entitiesBatch.stream().map(Entity::getIdValue), new Fetch().field(idAttr.getName())).map(Entity::getIdValue).collect(toSet());
        Object nonExistingEntityId = entitiesBatch.stream().map(Entity::getIdValue).filter(entityId -> !existingEntityIds.contains(entityId)).findFirst().orElseThrow(() -> new IllegalStateException("Not all entities in batch were updated but all are present in the repository."));
        throw new MolgenisValidationException(new ConstraintViolation(format("Cannot update [%s] with id [%s] because it does not exist", entityType.getId(), nonExistingEntityId.toString())));
    }
}
Also used : Fetch(org.molgenis.data.Fetch) ConstraintViolation(org.molgenis.data.validation.ConstraintViolation) MolgenisValidationException(org.molgenis.data.validation.MolgenisValidationException)

Aggregations

ConstraintViolation (org.molgenis.data.validation.ConstraintViolation)20 MolgenisValidationException (org.molgenis.data.validation.MolgenisValidationException)19 ServerErrorMessage (org.postgresql.util.ServerErrorMessage)7 Matcher (java.util.regex.Matcher)6 Attribute (org.molgenis.data.meta.model.Attribute)4 String.format (java.lang.String.format)2 LinkedHashMap (java.util.LinkedHashMap)2 Map (java.util.Map)2 Objects.requireNonNull (java.util.Objects.requireNonNull)2 MolgenisDataException (org.molgenis.data.MolgenisDataException)2 RepositoryCollection (org.molgenis.data.RepositoryCollection)2 AttributeType (org.molgenis.data.meta.AttributeType)2 EntityType (org.molgenis.data.meta.model.EntityType)2 EntityTypeDescription (org.molgenis.data.postgresql.identifier.EntityTypeDescription)2 Component (org.springframework.stereotype.Component)2 Lists.newArrayList (com.google.common.collect.Lists.newArrayList)1 Multimap (com.google.common.collect.Multimap)1 File (java.io.File)1 BatchUpdateException (java.sql.BatchUpdateException)1 SQLException (java.sql.SQLException)1