Search in sources :

Example 46 with Association

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

the class MappedEntityVisitor method computeMappingDefaults.

private void computeMappingDefaults(NamingStrategy namingStrategy, PersistentProperty property, Map<String, DataType> dataTypes, Map<String, String> dataConverters, VisitorContext context) {
    AnnotationMetadata annotationMetadata = property.getAnnotationMetadata();
    SourcePersistentProperty spp = (SourcePersistentProperty) property;
    PropertyElement propertyElement = spp.getPropertyElement();
    boolean isRelation = propertyElement.hasStereotype(Relation.class);
    DataType dataType = annotationMetadata.getValue(TypeDef.class, "type", DataType.class).orElse(null);
    String converter = annotationMetadata.stringValue(MappedProperty.class, "converter").orElseGet(() -> annotationMetadata.stringValue(TypeDef.class, "converter").orElse(null));
    if (Objects.equals(converter, Object.class.getName())) {
        converter = null;
    }
    if (converter == null) {
        ClassElement type = propertyElement.getGenericType();
        converter = TypeUtils.resolveDataConverter(type, dataConverters);
    }
    if (converter != null) {
        if (isRelation) {
            context.fail("Relation cannot have converter specified", propertyElement);
            return;
        }
        ClassElement persistedClassFromConverter = getPersistedClassFromConverter(converter, context);
        if (persistedClassFromConverter != null) {
            propertyElement.annotate(MappedProperty.class, builder -> {
                builder.member("converterPersistedType", new AnnotationClassValue<>(persistedClassFromConverter.getCanonicalName()));
            });
        }
        if (dataType == null) {
            dataType = getDataTypeFromConverter(propertyElement.getGenericType(), converter, dataTypes, context);
            if (dataType == null) {
                context.fail("Cannot recognize proper data type. Please use @TypeDef to specify one", propertyElement);
                return;
            }
        }
    } else {
        if (dataType == null && spp.getType().isEnum()) {
            if (spp.getOwner().getAnnotationMetadata().hasAnnotation("javax.persistence.Entity") || spp.getOwner().getAnnotationMetadata().hasAnnotation("jakarta.persistence.Entity")) {
                // JPA enums have default ORDINAL mapping for enums
                dataType = DataType.INTEGER;
            }
        }
        if (dataType == null) {
            ClassElement type = propertyElement.getGenericType();
            dataType = TypeUtils.resolveDataType(type, dataTypes);
        }
    }
    if (dataType == DataType.ENTITY && !isRelation) {
        propertyElement = (PropertyElement) propertyElement.annotate(Relation.class, builder -> builder.value(Relation.Kind.MANY_TO_ONE));
    } else if (isRelation) {
        Relation.Kind kind = propertyElement.enumValue(Relation.class, Relation.Kind.class).orElse(Relation.Kind.MANY_TO_ONE);
        if (kind == Relation.Kind.EMBEDDED || kind == Relation.Kind.MANY_TO_ONE) {
            if (propertyElement.stringValue(Relation.class, "mappedBy").isPresent()) {
                context.fail("Relation " + kind + " doesn't support 'mappedBy'.", propertyElement);
            }
        }
        if (kind == Relation.Kind.EMBEDDED) {
            // handled embedded
            SourcePersistentEntity embeddedEntity = entityResolver.apply(propertyElement.getType());
            List<SourcePersistentProperty> persistentProperties = embeddedEntity.getPersistentProperties();
            List<AnnotationValue<Property>> embeddedProperties = new ArrayList<>(persistentProperties.size());
            for (SourcePersistentProperty embeddedProperty : persistentProperties) {
                if (!(embeddedProperty instanceof Association)) {
                    String mappedName = embeddedProperty.stringValue(MappedProperty.class).orElseGet(() -> namingStrategy.mappedName(property.getName() + embeddedProperty.getCapitilizedName()));
                    AnnotationValue<Property> av = AnnotationValue.builder(Property.class).value(mappedName).member("name", embeddedProperty.getName()).build();
                    embeddedProperties.add(av);
                }
            // else {
            // // TODO: handle nested embedded
            // }
            }
            propertyElement.annotate(MappedProperty.class, builder -> builder.member(MappedProperty.EMBEDDED_PROPERTIES, embeddedProperties.toArray(new AnnotationValue[0])));
        }
    }
    Optional<String> mapping = annotationMetadata.stringValue(MappedProperty.class);
    if (mappedEntity && !mapping.isPresent()) {
        propertyElement.annotate(MappedProperty.class, builder -> builder.value(namingStrategy.mappedName(spp)));
    }
    if (dataType != DataType.OBJECT) {
        DataType finalDataType = dataType;
        propertyElement.annotate(MappedProperty.class, builder -> builder.member("type", finalDataType));
    }
    if (converter != null) {
        String finalConverter = converter;
        propertyElement.annotate(MappedProperty.class, builder -> builder.member("converter", new AnnotationClassValue<>(finalConverter)));
    }
}
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) ClassElement(io.micronaut.inject.ast.ClassElement) AnnotationClassValue(io.micronaut.core.annotation.AnnotationClassValue) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata) Relation(io.micronaut.data.annotation.Relation) Association(io.micronaut.data.model.Association) SourcePersistentProperty(io.micronaut.data.processor.model.SourcePersistentProperty) TypeDef(io.micronaut.data.annotation.TypeDef) MappedProperty(io.micronaut.data.annotation.MappedProperty) DataType(io.micronaut.data.model.DataType) AnnotationValue(io.micronaut.core.annotation.AnnotationValue) ArrayList(java.util.ArrayList) List(java.util.List) SourcePersistentProperty(io.micronaut.data.processor.model.SourcePersistentProperty) MappedProperty(io.micronaut.data.annotation.MappedProperty) PersistentProperty(io.micronaut.data.model.PersistentProperty) Property(io.micronaut.context.annotation.Property) PropertyElement(io.micronaut.inject.ast.PropertyElement)

Aggregations

Association (io.micronaut.data.model.Association)46 PersistentProperty (io.micronaut.data.model.PersistentProperty)21 ArrayList (java.util.ArrayList)21 Embedded (io.micronaut.data.model.Embedded)17 StringJoiner (java.util.StringJoiner)16 PersistentPropertyPath (io.micronaut.data.model.PersistentPropertyPath)15 NonNull (io.micronaut.core.annotation.NonNull)14 PersistentEntity (io.micronaut.data.model.PersistentEntity)14 List (java.util.List)14 AnnotationMetadata (io.micronaut.core.annotation.AnnotationMetadata)13 Relation (io.micronaut.data.annotation.Relation)11 NamingStrategy (io.micronaut.data.model.naming.NamingStrategy)11 JoinPath (io.micronaut.data.model.query.JoinPath)11 Map (java.util.Map)11 HashMap (java.util.HashMap)10 Optional (java.util.Optional)10 Collectors (java.util.stream.Collectors)10 MappedEntity (io.micronaut.data.annotation.MappedEntity)9 QueryModel (io.micronaut.data.model.query.QueryModel)9 Collections (java.util.Collections)9