Search in sources :

Example 1 with SourcePersistentProperty

use of io.micronaut.data.processor.model.SourcePersistentProperty in project micronaut-data by micronaut-projects.

the class MappedEntityVisitor method visitClass.

@Override
public void visitClass(ClassElement element, VisitorContext context) {
    NamingStrategy namingStrategy = resolveNamingStrategy(element);
    Optional<String> targetName = element.stringValue(MappedEntity.class);
    SourcePersistentEntity entity = entityResolver.apply(element);
    if (isMappedEntity() && !targetName.isPresent()) {
        element.annotate(MappedEntity.class, builder -> {
            String mappedName = namingStrategy.mappedName(entity);
            builder.value(mappedName);
        });
    }
    Map<String, DataType> dataTypes = getConfiguredDataTypes(element);
    Map<String, String> dataConverters = getConfiguredDataConverters(element);
    List<SourcePersistentProperty> properties = entity.getPersistentProperties();
    final List<AnnotationValue<Index>> indexes = properties.stream().filter(x -> ((PersistentProperty) x).findAnnotation(Indexes.class).isPresent()).map(prop -> prop.findAnnotation(Index.class)).flatMap(o -> o.map(Stream::of).orElseGet(Stream::empty)).collect(Collectors.toList());
    if (!indexes.isEmpty()) {
        element.annotate(Indexes.class, builder -> builder.values(indexes.toArray(new AnnotationValue[] {})));
    }
    for (PersistentProperty property : properties) {
        computeMappingDefaults(namingStrategy, property, dataTypes, dataConverters, context);
    }
    SourcePersistentProperty identity = entity.getIdentity();
    if (identity != null) {
        computeMappingDefaults(namingStrategy, identity, dataTypes, dataConverters, context);
    }
    SourcePersistentProperty[] compositeIdentities = entity.getCompositeIdentity();
    if (compositeIdentities != null) {
        for (SourcePersistentProperty compositeIdentity : compositeIdentities) {
            computeMappingDefaults(namingStrategy, compositeIdentity, dataTypes, dataConverters, context);
        }
    }
    SourcePersistentProperty version = entity.getVersion();
    if (version != null) {
        computeMappingDefaults(namingStrategy, version, dataTypes, dataConverters, context);
    }
}
Also used : DataType(io.micronaut.data.model.DataType) MappedEntity(io.micronaut.data.annotation.MappedEntity) SourcePersistentProperty(io.micronaut.data.processor.model.SourcePersistentProperty) ClassElement(io.micronaut.inject.ast.ClassElement) HashMap(java.util.HashMap) TypeDef(io.micronaut.data.annotation.TypeDef) Function(java.util.function.Function) ArrayList(java.util.ArrayList) Utils.getConfiguredDataTypes(io.micronaut.data.processor.visitors.Utils.getConfiguredDataTypes) Utils.getConfiguredDataConverters(io.micronaut.data.processor.visitors.Utils.getConfiguredDataConverters) TypeElementVisitor(io.micronaut.inject.visitor.TypeElementVisitor) MappedProperty(io.micronaut.data.annotation.MappedProperty) PropertyElement(io.micronaut.inject.ast.PropertyElement) InstantiationUtils(io.micronaut.core.reflect.InstantiationUtils) Map(java.util.Map) TypeUtils(io.micronaut.data.processor.visitors.finders.TypeUtils) AnnotationClassValue(io.micronaut.core.annotation.AnnotationClassValue) NamingStrategies(io.micronaut.data.model.naming.NamingStrategies) PersistentProperty(io.micronaut.data.model.PersistentProperty) Property(io.micronaut.context.annotation.Property) Index(io.micronaut.data.annotation.Index) NamingStrategy(io.micronaut.data.model.naming.NamingStrategy) SourcePersistentEntity(io.micronaut.data.processor.model.SourcePersistentEntity) Collectors(java.util.stream.Collectors) Indexes(io.micronaut.data.annotation.Indexes) Objects(java.util.Objects) NonNull(io.micronaut.core.annotation.NonNull) VisitorContext(io.micronaut.inject.visitor.VisitorContext) List(java.util.List) Association(io.micronaut.data.model.Association) Stream(java.util.stream.Stream) AnnotationValue(io.micronaut.core.annotation.AnnotationValue) Optional(java.util.Optional) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata) AttributeConverter(io.micronaut.data.model.runtime.convert.AttributeConverter) Relation(io.micronaut.data.annotation.Relation) SourcePersistentEntity(io.micronaut.data.processor.model.SourcePersistentEntity) Index(io.micronaut.data.annotation.Index) SourcePersistentProperty(io.micronaut.data.processor.model.SourcePersistentProperty) PersistentProperty(io.micronaut.data.model.PersistentProperty) Indexes(io.micronaut.data.annotation.Indexes) NamingStrategy(io.micronaut.data.model.naming.NamingStrategy) SourcePersistentProperty(io.micronaut.data.processor.model.SourcePersistentProperty) DataType(io.micronaut.data.model.DataType) AnnotationValue(io.micronaut.core.annotation.AnnotationValue) Stream(java.util.stream.Stream)

Example 2 with SourcePersistentProperty

use of io.micronaut.data.processor.model.SourcePersistentProperty in project micronaut-data by micronaut-projects.

the class UpdateMethodMatcher method batchUpdate.

private UpdateCriteriaMethodMatch batchUpdate(java.util.regex.Matcher matcher, ParameterElement idParameter) {
    return new UpdateCriteriaMethodMatch(matcher) {

        @Override
        protected <T> void applyPredicates(String querySequence, ParameterElement[] parameters, PersistentEntityRoot<T> root, PersistentEntityCriteriaUpdate<T> query, SourcePersistentEntityCriteriaBuilder cb) {
            super.applyPredicates(querySequence, parameters, root, query, cb);
            ParameterElement versionParameter = Arrays.stream(parameters).filter(p -> p.hasAnnotation(Version.class)).findFirst().orElse(null);
            Predicate predicate;
            if (versionParameter != null) {
                predicate = cb.and(cb.equal(root.id(), cb.parameter(idParameter)), cb.equal(root.version(), cb.parameter(versionParameter)));
            } else {
                predicate = cb.equal(root.id(), cb.parameter(idParameter));
            }
            query.where(predicate);
        }

        @Override
        protected <T> void applyPredicates(List<ParameterElement> parameters, PersistentEntityRoot<T> root, PersistentEntityCriteriaUpdate<T> query, SourcePersistentEntityCriteriaBuilder cb) {
            ParameterElement versionParameter = parameters.stream().filter(p -> p.hasAnnotation(Version.class)).findFirst().orElse(null);
            Predicate predicate;
            if (versionParameter != null) {
                predicate = cb.and(cb.equal(root.id(), cb.parameter(idParameter)), cb.equal(root.version(), cb.parameter(versionParameter)));
            } else {
                predicate = cb.equal(root.id(), cb.parameter(idParameter));
            }
            query.where(predicate);
        }

        @Override
        protected <T> void addPropertiesToUpdate(MethodMatchContext matchContext, PersistentEntityRoot<T> root, PersistentEntityCriteriaUpdate<T> query, SourcePersistentEntityCriteriaBuilder cb) {
            List<ParameterElement> parameters = matchContext.getParametersNotInRole();
            List<ParameterElement> remainingParameters = parameters.stream().filter(p -> !p.hasAnnotation(Id.class) && !p.hasAnnotation(Version.class)).collect(Collectors.toList());
            ParameterElement idParameter = parameters.stream().filter(p -> p.hasAnnotation(Id.class)).findFirst().orElse(null);
            if (idParameter == null) {
                throw new MatchFailedException("ID required for update method, but not specified");
            }
            SourcePersistentEntity entity = (SourcePersistentEntity) root.getPersistentEntity();
            // Validate @IdClass for composite entity
            if (entity.hasIdentity()) {
                SourcePersistentProperty identity = entity.getIdentity();
                String idType = TypeUtils.getTypeName(identity.getType());
                String idParameterType = TypeUtils.getTypeName(idParameter.getType());
                if (!idType.equals(idParameterType)) {
                    throw new MatchFailedException("ID type of method [" + idParameterType + "] does not match ID type of entity: " + idType);
                }
            } else {
                throw new MatchFailedException("Cannot update by ID for entity that has no ID");
            }
            for (ParameterElement parameter : remainingParameters) {
                String name = getParameterName(parameter);
                SourcePersistentProperty prop = entity.getPropertyByName(name);
                if (prop == null) {
                    throw new MatchFailedException("Cannot update non-existent property: " + name);
                } else {
                    if (prop.isGenerated()) {
                        throw new MatchFailedException("Cannot update a generated property: " + name);
                    } else {
                        query.set(name, cb.parameter(parameter));
                    }
                }
            }
        }
    };
}
Also used : SourcePersistentEntityCriteriaBuilder(io.micronaut.data.processor.model.criteria.SourcePersistentEntityCriteriaBuilder) Arrays(java.util.Arrays) Parameter(io.micronaut.context.annotation.Parameter) MappedEntity(io.micronaut.data.annotation.MappedEntity) ParameterExpression(jakarta.persistence.criteria.ParameterExpression) SourcePersistentProperty(io.micronaut.data.processor.model.SourcePersistentProperty) ClassElement(io.micronaut.inject.ast.ClassElement) Internal(io.micronaut.core.annotation.Internal) AbstractPersistentEntityCriteriaUpdate(io.micronaut.data.model.jpa.criteria.impl.AbstractPersistentEntityCriteriaUpdate) DataInterceptor(io.micronaut.data.intercept.DataInterceptor) ParameterElement(io.micronaut.inject.ast.ParameterElement) Version(io.micronaut.data.annotation.Version) Map(java.util.Map) Id(io.micronaut.data.annotation.Id) PersistentPropertyPath(io.micronaut.data.model.PersistentPropertyPath) UpdateCriteriaMethodMatch(io.micronaut.data.processor.visitors.finders.criteria.UpdateCriteriaMethodMatch) MatchFailedException(io.micronaut.data.processor.visitors.MatchFailedException) Predicate(jakarta.persistence.criteria.Predicate) AutoPopulated(io.micronaut.data.annotation.AutoPopulated) Set(java.util.Set) SourcePersistentEntity(io.micronaut.data.processor.model.SourcePersistentEntity) Collectors(java.util.stream.Collectors) PersistentEntityCriteriaUpdate(io.micronaut.data.model.jpa.criteria.PersistentEntityCriteriaUpdate) PersistentEntityRoot(io.micronaut.data.model.jpa.criteria.PersistentEntityRoot) List(java.util.List) Association(io.micronaut.data.model.Association) Stream(java.util.stream.Stream) MethodMatchContext(io.micronaut.data.processor.visitors.MethodMatchContext) MethodElement(io.micronaut.inject.ast.MethodElement) MatchFailedException(io.micronaut.data.processor.visitors.MatchFailedException) SourcePersistentEntity(io.micronaut.data.processor.model.SourcePersistentEntity) Predicate(jakarta.persistence.criteria.Predicate) SourcePersistentEntityCriteriaBuilder(io.micronaut.data.processor.model.criteria.SourcePersistentEntityCriteriaBuilder) MethodMatchContext(io.micronaut.data.processor.visitors.MethodMatchContext) PersistentEntityRoot(io.micronaut.data.model.jpa.criteria.PersistentEntityRoot) SourcePersistentProperty(io.micronaut.data.processor.model.SourcePersistentProperty) AbstractPersistentEntityCriteriaUpdate(io.micronaut.data.model.jpa.criteria.impl.AbstractPersistentEntityCriteriaUpdate) PersistentEntityCriteriaUpdate(io.micronaut.data.model.jpa.criteria.PersistentEntityCriteriaUpdate) Version(io.micronaut.data.annotation.Version) UpdateCriteriaMethodMatch(io.micronaut.data.processor.visitors.finders.criteria.UpdateCriteriaMethodMatch) List(java.util.List) ParameterElement(io.micronaut.inject.ast.ParameterElement) Id(io.micronaut.data.annotation.Id)

Example 3 with SourcePersistentProperty

use of io.micronaut.data.processor.model.SourcePersistentProperty in project micronaut-data by micronaut-projects.

the class AbstractCriteriaMethodMatch method provideParams.

private <T> List<ParameterExpression<T>> provideParams(Iterator<ParameterElement> parameters, int requiredParameters, String restrictionName, SourcePersistentEntityCriteriaBuilder cb, @Nullable Expression<?> expression) {
    if (requiredParameters == 0) {
        return Collections.emptyList();
    }
    List<ParameterExpression<T>> params = new ArrayList<>(requiredParameters);
    for (int i = 0; i < requiredParameters; i++) {
        if (!parameters.hasNext()) {
            throw new MatchFailedException("Insufficient arguments to method criteria: " + restrictionName);
        }
        ParameterElement parameter = parameters.next();
        ClassElement genericType = parameter.getGenericType();
        if (TypeUtils.isContainerType(genericType)) {
            genericType = genericType.getFirstTypeArgument().orElse(genericType);
        }
        if (expression instanceof io.micronaut.data.model.jpa.criteria.PersistentPropertyPath) {
            io.micronaut.data.model.jpa.criteria.PersistentPropertyPath<?> pp = (io.micronaut.data.model.jpa.criteria.PersistentPropertyPath<?>) expression;
            PersistentPropertyPath propertyPath = PersistentPropertyPath.of(pp.getAssociations(), pp.getProperty());
            if (!isValidType(genericType, (SourcePersistentProperty) propertyPath.getProperty())) {
                SourcePersistentProperty property = (SourcePersistentProperty) propertyPath.getProperty();
                throw new IllegalArgumentException("Parameter [" + genericType.getType().getName() + " " + parameter.getName() + "] is not compatible with property [" + property.getType().getName() + " " + property.getName() + "] of entity: " + property.getOwner().getName());
            }
        }
        ParameterExpression p = cb.parameter(parameter);
        params.add(p);
    }
    return params;
}
Also used : MatchFailedException(io.micronaut.data.processor.visitors.MatchFailedException) ArrayList(java.util.ArrayList) ClassElement(io.micronaut.inject.ast.ClassElement) PersistentPropertyPath(io.micronaut.data.model.PersistentPropertyPath) SourcePersistentProperty(io.micronaut.data.processor.model.SourcePersistentProperty) ParameterExpression(jakarta.persistence.criteria.ParameterExpression) ParameterElement(io.micronaut.inject.ast.ParameterElement)

Example 4 with SourcePersistentProperty

use of io.micronaut.data.processor.model.SourcePersistentProperty in project micronaut-data by micronaut-projects.

the class SourcePersistentEntityCriteriaQueryImpl method getQueryResultTypeName.

@Override
public String getQueryResultTypeName() {
    if (selection instanceof ISelection) {
        String[] result = new String[1];
        ((SelectionVisitable) selection).accept(new SelectionVisitor() {

            @Override
            public void visit(Predicate predicate) {
            }

            @Override
            public void visit(PersistentPropertyPath<?> persistentPropertyPath) {
                result[0] = ((SourcePersistentPropertyPath) persistentPropertyPath).getProperty().getType().getName();
            }

            @Override
            public void visit(AliasedSelection<?> aliasedSelection) {
                ((SelectionVisitable) aliasedSelection.getSelection()).accept(this);
            }

            @Override
            public void visit(PersistentEntityRoot<?> entityRoot) {
                result[0] = ((SourcePersistentEntity) entityRoot.getPersistentEntity()).getType().getName();
            }

            @Override
            public void visit(AggregateExpression<?, ?> aggregateExpression) {
                switch(aggregateExpression.getType()) {
                    case COUNT:
                    case COUNT_DISTINCT:
                        result[0] = Long.class.getName();
                        break;
                    case MAX:
                    case MIN:
                        result[0] = requireProperty(aggregateExpression.getExpression()).getProperty().getTypeName();
                        break;
                    case SUM:
                    case AVG:
                        ClassElement type = ((SourcePersistentProperty) requireProperty(aggregateExpression.getExpression()).getProperty()).getType();
                        if (aggregateExpression.getExpressionType() != null) {
                            result[0] = aggregateExpression.getExpressionType().getName();
                        }
                        if (TypeUtils.isNumber(type)) {
                            result[0] = Number.class.getName();
                        } else {
                            result[0] = type.getName();
                        }
                        break;
                    default:
                        return;
                }
            }

            @Override
            public void visit(CompoundSelection<?> compoundSelection) {
                if (compoundSelection.getCompoundSelectionItems().size() == 1) {
                    // Multiple selection shouldn't result in one type
                    compoundSelection.getCompoundSelectionItems().forEach(s -> ((SelectionVisitable) s).accept(this));
                }
            }

            @Override
            public void visit(LiteralExpression<?> literalExpression) {
                result[0] = literalExpression.getValue().getClass().getName();
            }

            @Override
            public void visit(IdExpression<?, ?> idExpression) {
                SourcePersistentEntity persistentEntity = (SourcePersistentEntity) idExpression.getRoot().getPersistentEntity();
                if (persistentEntity.hasCompositeIdentity()) {
                    throw new IllegalStateException("IdClass is unknown!");
                }
                result[0] = persistentEntity.getIdentity().getType().getName();
            }
        });
        return result[0];
    }
    return null;
}
Also used : IdExpression(io.micronaut.data.model.jpa.criteria.impl.IdExpression) Predicate(jakarta.persistence.criteria.Predicate) LiteralExpression(io.micronaut.data.model.jpa.criteria.impl.LiteralExpression) SelectionVisitor(io.micronaut.data.model.jpa.criteria.impl.SelectionVisitor) SourcePersistentProperty(io.micronaut.data.processor.model.SourcePersistentProperty) ClassElement(io.micronaut.inject.ast.ClassElement) Internal(io.micronaut.core.annotation.Internal) SourcePersistentEntity(io.micronaut.data.processor.model.SourcePersistentEntity) SourcePersistentEntityCriteriaQuery(io.micronaut.data.processor.model.criteria.SourcePersistentEntityCriteriaQuery) Function(java.util.function.Function) ISelection(io.micronaut.data.model.jpa.criteria.ISelection) PersistentEntityRoot(io.micronaut.data.model.jpa.criteria.PersistentEntityRoot) AbstractPersistentEntityCriteriaQuery(io.micronaut.data.model.jpa.criteria.impl.AbstractPersistentEntityCriteriaQuery) AggregateExpression(io.micronaut.data.model.jpa.criteria.impl.selection.AggregateExpression) PersistentEntity(io.micronaut.data.model.PersistentEntity) CriteriaUtils.requireProperty(io.micronaut.data.model.jpa.criteria.impl.CriteriaUtils.requireProperty) PersistentPropertyPath(io.micronaut.data.model.jpa.criteria.PersistentPropertyPath) SelectionVisitable(io.micronaut.data.model.jpa.criteria.impl.SelectionVisitable) TypeUtils(io.micronaut.data.processor.visitors.finders.TypeUtils) CompoundSelection(io.micronaut.data.model.jpa.criteria.impl.selection.CompoundSelection) AliasedSelection(io.micronaut.data.model.jpa.criteria.impl.selection.AliasedSelection) SourcePersistentEntity(io.micronaut.data.processor.model.SourcePersistentEntity) SelectionVisitor(io.micronaut.data.model.jpa.criteria.impl.SelectionVisitor) ClassElement(io.micronaut.inject.ast.ClassElement) Predicate(jakarta.persistence.criteria.Predicate) ISelection(io.micronaut.data.model.jpa.criteria.ISelection) SelectionVisitable(io.micronaut.data.model.jpa.criteria.impl.SelectionVisitable)

Example 5 with SourcePersistentProperty

use of io.micronaut.data.processor.model.SourcePersistentProperty in project micronaut-data by micronaut-projects.

the class SourcePersistentEntityPath method get.

@Override
default <Y> PersistentPropertyPath<Y> get(String attributeName) {
    SourcePersistentProperty property = getPersistentEntity().getPropertyByName(attributeName);
    if (property == null) {
        throw new IllegalStateException("Cannot query entity [" + getPersistentEntity().getSimpleName() + "] on non-existent property: " + attributeName);
    }
    if (this instanceof PersistentAssociationPath) {
        PersistentAssociationPath<?, ?> associationPath = (PersistentAssociationPath) this;
        List<Association> associations = associationPath.getAssociations();
        List<Association> newAssociations = new ArrayList<>(associations.size() + 1);
        newAssociations.addAll(associations);
        newAssociations.add(associationPath.getAssociation());
        return new SourcePersistentPropertyPathImpl<>(this, newAssociations, property);
    }
    return new SourcePersistentPropertyPathImpl<>(this, Collections.emptyList(), property);
}
Also used : Association(io.micronaut.data.model.Association) SourcePersistentProperty(io.micronaut.data.processor.model.SourcePersistentProperty) ArrayList(java.util.ArrayList) PersistentAssociationPath(io.micronaut.data.model.jpa.criteria.PersistentAssociationPath)

Aggregations

SourcePersistentProperty (io.micronaut.data.processor.model.SourcePersistentProperty)10 ClassElement (io.micronaut.inject.ast.ClassElement)9 Map (java.util.Map)7 SourcePersistentEntity (io.micronaut.data.processor.model.SourcePersistentEntity)6 ArrayList (java.util.ArrayList)6 List (java.util.List)6 Association (io.micronaut.data.model.Association)5 PersistentProperty (io.micronaut.data.model.PersistentProperty)5 TypeUtils (io.micronaut.data.processor.visitors.finders.TypeUtils)5 ParameterElement (io.micronaut.inject.ast.ParameterElement)5 Collectors (java.util.stream.Collectors)5 Internal (io.micronaut.core.annotation.Internal)4 NonNull (io.micronaut.core.annotation.NonNull)4 MappedEntity (io.micronaut.data.annotation.MappedEntity)4 DataType (io.micronaut.data.model.DataType)4 PersistentPropertyPath (io.micronaut.data.model.PersistentPropertyPath)4 MatchFailedException (io.micronaut.data.processor.visitors.MatchFailedException)4 Function (java.util.function.Function)4 Parameter (io.micronaut.context.annotation.Parameter)3 AnnotationClassValue (io.micronaut.core.annotation.AnnotationClassValue)3