Search in sources :

Example 1 with Join

use of io.micronaut.data.annotation.Join in project micronaut-data by micronaut-projects.

the class AbstractCriteriaMethodMatch method applyJoinSpecs.

protected final void applyJoinSpecs(PersistentEntityRoot<?> root, @NonNull List<AnnotationValue<Join>> joinSpecs) {
    for (AnnotationValue<Join> joinSpec : joinSpecs) {
        String path = joinSpec.stringValue().orElse(null);
        Join.Type type = joinSpec.enumValue("type", Join.Type.class).orElse(Join.Type.FETCH);
        String alias = joinSpec.stringValue("alias").orElse(null);
        if (path != null) {
            PersistentPropertyPath propertyPath = root.getPersistentEntity().getPropertyPath(path);
            if (propertyPath == null || !(propertyPath.getProperty() instanceof Association)) {
                throw new MatchFailedException("Invalid join spec [" + path + "]. Property is not an association!");
            } else {
                PersistentEntityFrom<?, ?> p = root;
                for (Association association : propertyPath.getAssociations()) {
                    p = p.join(association.getName(), type);
                }
                if (alias != null) {
                    p.join(propertyPath.getProperty().getName(), type, alias);
                } else {
                    p.join(propertyPath.getProperty().getName(), type);
                }
            }
        }
    }
}
Also used : Association(io.micronaut.data.model.Association) MatchFailedException(io.micronaut.data.processor.visitors.MatchFailedException) Join(io.micronaut.data.annotation.Join) PersistentPropertyPath(io.micronaut.data.model.PersistentPropertyPath)

Example 2 with Join

use of io.micronaut.data.annotation.Join in project micronaut-data by micronaut-projects.

the class SqlQueryBuilder method buildJoinTableInsert.

/**
 * Builds a join table insert statement for a given entity and association.
 *
 * @param entity      The entity
 * @param association The association
 * @return The join table insert statement
 */
@NonNull
public String buildJoinTableInsert(@NonNull PersistentEntity entity, @NonNull Association association) {
    if (!isForeignKeyWithJoinTable(association)) {
        throw new IllegalArgumentException("Join table inserts can only be built for foreign key associations that are mapped with a join table.");
    } else {
        Optional<Association> inverseSide = association.getInverseSide().map(Function.identity());
        Association owningAssociation = inverseSide.orElse(association);
        AnnotationMetadata annotationMetadata = owningAssociation.getAnnotationMetadata();
        NamingStrategy namingStrategy = entity.getNamingStrategy();
        String joinTableName = annotationMetadata.stringValue(ANN_JOIN_TABLE, "name").orElseGet(() -> namingStrategy.mappedName(association));
        List<String> leftJoinColumns = resolveJoinTableJoinColumns(annotationMetadata, true, entity, namingStrategy);
        List<String> rightJoinColumns = resolveJoinTableJoinColumns(annotationMetadata, false, association.getAssociatedEntity(), namingStrategy);
        boolean escape = shouldEscape(entity);
        String columns = Stream.concat(leftJoinColumns.stream(), rightJoinColumns.stream()).map(columnName -> escape ? quote(columnName) : columnName).collect(Collectors.joining(","));
        String placeholders = IntStream.range(0, leftJoinColumns.size() + rightJoinColumns.size()).mapToObj(i -> "?").collect(Collectors.joining(","));
        return INSERT_INTO + quote(joinTableName) + " (" + columns + ") VALUES (" + placeholders + ")";
    }
}
Also used : DataType(io.micronaut.data.model.DataType) SqlMembers(io.micronaut.data.annotation.sql.SqlMembers) Arrays(java.util.Arrays) IDENTITY(io.micronaut.data.annotation.GeneratedValue.Type.IDENTITY) ListIterator(java.util.ListIterator) ArrayUtils(io.micronaut.core.util.ArrayUtils) SEQUENCE(io.micronaut.data.annotation.GeneratedValue.Type.SEQUENCE) MappedProperty(io.micronaut.data.annotation.MappedProperty) GeneratedValue(io.micronaut.data.annotation.GeneratedValue) Locale(java.util.Locale) Map(java.util.Map) QueryResult(io.micronaut.data.model.query.builder.QueryResult) ArgumentUtils(io.micronaut.core.util.ArgumentUtils) PersistentPropertyPath(io.micronaut.data.model.PersistentPropertyPath) PersistentProperty(io.micronaut.data.model.PersistentProperty) Index(io.micronaut.data.annotation.Index) MappingException(io.micronaut.data.exceptions.MappingException) Collection(java.util.Collection) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) AUTO(io.micronaut.data.annotation.GeneratedValue.Type.AUTO) StringUtils(io.micronaut.core.util.StringUtils) AbstractSqlLikeQueryBuilder(io.micronaut.data.model.query.builder.AbstractSqlLikeQueryBuilder) List(java.util.List) Stream(java.util.stream.Stream) UUID(io.micronaut.data.annotation.GeneratedValue.Type.UUID) AnnotationValue(io.micronaut.core.annotation.AnnotationValue) Annotation(java.lang.annotation.Annotation) Optional(java.util.Optional) Experimental(io.micronaut.core.annotation.Experimental) Pattern(java.util.regex.Pattern) Relation(io.micronaut.data.annotation.Relation) IntStream(java.util.stream.IntStream) QueryParameterBinding(io.micronaut.data.model.query.builder.QueryParameterBinding) Join(io.micronaut.data.annotation.Join) Creator(io.micronaut.core.annotation.Creator) QueryModel(io.micronaut.data.model.query.QueryModel) MappedEntity(io.micronaut.data.annotation.MappedEntity) HashMap(java.util.HashMap) OptionalInt(java.util.OptionalInt) Function(java.util.function.Function) ArrayList(java.util.ArrayList) Embedded(io.micronaut.data.model.Embedded) Pageable(io.micronaut.data.model.Pageable) BiConsumer(java.util.function.BiConsumer) Clob(java.sql.Clob) NamingStrategy(io.micronaut.data.model.naming.NamingStrategy) Indexes(io.micronaut.data.annotation.Indexes) NonNull(io.micronaut.core.annotation.NonNull) JoinPath(io.micronaut.data.model.query.JoinPath) Association(io.micronaut.data.model.Association) PersistentEntity(io.micronaut.data.model.PersistentEntity) CollectionUtils(io.micronaut.core.util.CollectionUtils) StringJoiner(java.util.StringJoiner) QueryBuilder(io.micronaut.data.model.query.builder.QueryBuilder) Repository(io.micronaut.data.annotation.Repository) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata) Blob(java.sql.Blob) Collections(java.util.Collections) NamingStrategy(io.micronaut.data.model.naming.NamingStrategy) Association(io.micronaut.data.model.Association) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata) NonNull(io.micronaut.core.annotation.NonNull)

Example 3 with Join

use of io.micronaut.data.annotation.Join in project micronaut-data by micronaut-projects.

the class SqlQueryBuilder method join.

private void join(StringBuilder sb, String joinType, QueryState queryState, PersistentEntity associatedEntity, PersistentEntity associationOwner, String leftTableAlias, String rightTableAlias, List<Association> leftPropertyAssociations, PersistentProperty leftProperty, List<Association> rightPropertyAssociations, PersistentProperty rightProperty) {
    final boolean escape = shouldEscape(associationOwner);
    List<String> onLeftColumns = new ArrayList<>();
    List<String> onRightColumns = new ArrayList<>();
    Association association = null;
    if (leftProperty instanceof Association) {
        association = (Association) leftProperty;
    } else if (rightProperty instanceof Association) {
        association = (Association) rightProperty;
    }
    if (association != null) {
        Optional<Association> inverse = association.getInverseSide().map(Function.identity());
        Association owner = inverse.orElse(association);
        boolean isOwner = leftProperty == owner;
        AnnotationValue<Annotation> joinColumnsHolder = owner.getAnnotationMetadata().getAnnotation(ANN_JOIN_COLUMNS);
        if (joinColumnsHolder != null) {
            onLeftColumns.addAll(joinColumnsHolder.getAnnotations("value").stream().map(ann -> ann.stringValue(isOwner ? "name" : "referencedColumnName").orElse(null)).filter(Objects::nonNull).collect(Collectors.toList()));
            onRightColumns.addAll(joinColumnsHolder.getAnnotations("value").stream().map(ann -> ann.stringValue(isOwner ? "referencedColumnName" : "name").orElse(null)).filter(Objects::nonNull).collect(Collectors.toList()));
        }
    }
    if (onLeftColumns.isEmpty()) {
        traversePersistentProperties(leftProperty, (associations, p) -> {
            String column = leftProperty.getOwner().getNamingStrategy().mappedName(merge(leftPropertyAssociations, associations), p);
            onLeftColumns.add(column);
        });
        if (onLeftColumns.isEmpty()) {
            throw new MappingException("Cannot join on entity [" + leftProperty.getOwner().getName() + "] that has no declared ID");
        }
    }
    if (onRightColumns.isEmpty()) {
        traversePersistentProperties(rightProperty, (associations, p) -> {
            String column = rightProperty.getOwner().getNamingStrategy().mappedName(merge(rightPropertyAssociations, associations), p);
            onRightColumns.add(column);
        });
    }
    join(sb, queryState.getQueryModel(), joinType, getTableName(associatedEntity), rightTableAlias, leftTableAlias, escape ? onLeftColumns.stream().map(this::quote).collect(Collectors.toList()) : onLeftColumns, escape ? onRightColumns.stream().map(this::quote).collect(Collectors.toList()) : onRightColumns);
}
Also used : DataType(io.micronaut.data.model.DataType) SqlMembers(io.micronaut.data.annotation.sql.SqlMembers) Arrays(java.util.Arrays) IDENTITY(io.micronaut.data.annotation.GeneratedValue.Type.IDENTITY) ListIterator(java.util.ListIterator) ArrayUtils(io.micronaut.core.util.ArrayUtils) SEQUENCE(io.micronaut.data.annotation.GeneratedValue.Type.SEQUENCE) MappedProperty(io.micronaut.data.annotation.MappedProperty) GeneratedValue(io.micronaut.data.annotation.GeneratedValue) Locale(java.util.Locale) Map(java.util.Map) QueryResult(io.micronaut.data.model.query.builder.QueryResult) ArgumentUtils(io.micronaut.core.util.ArgumentUtils) PersistentPropertyPath(io.micronaut.data.model.PersistentPropertyPath) PersistentProperty(io.micronaut.data.model.PersistentProperty) Index(io.micronaut.data.annotation.Index) MappingException(io.micronaut.data.exceptions.MappingException) Collection(java.util.Collection) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) AUTO(io.micronaut.data.annotation.GeneratedValue.Type.AUTO) StringUtils(io.micronaut.core.util.StringUtils) AbstractSqlLikeQueryBuilder(io.micronaut.data.model.query.builder.AbstractSqlLikeQueryBuilder) List(java.util.List) Stream(java.util.stream.Stream) UUID(io.micronaut.data.annotation.GeneratedValue.Type.UUID) AnnotationValue(io.micronaut.core.annotation.AnnotationValue) Annotation(java.lang.annotation.Annotation) Optional(java.util.Optional) Experimental(io.micronaut.core.annotation.Experimental) Pattern(java.util.regex.Pattern) Relation(io.micronaut.data.annotation.Relation) IntStream(java.util.stream.IntStream) QueryParameterBinding(io.micronaut.data.model.query.builder.QueryParameterBinding) Join(io.micronaut.data.annotation.Join) Creator(io.micronaut.core.annotation.Creator) QueryModel(io.micronaut.data.model.query.QueryModel) MappedEntity(io.micronaut.data.annotation.MappedEntity) HashMap(java.util.HashMap) OptionalInt(java.util.OptionalInt) Function(java.util.function.Function) ArrayList(java.util.ArrayList) Embedded(io.micronaut.data.model.Embedded) Pageable(io.micronaut.data.model.Pageable) BiConsumer(java.util.function.BiConsumer) Clob(java.sql.Clob) NamingStrategy(io.micronaut.data.model.naming.NamingStrategy) Indexes(io.micronaut.data.annotation.Indexes) NonNull(io.micronaut.core.annotation.NonNull) JoinPath(io.micronaut.data.model.query.JoinPath) Association(io.micronaut.data.model.Association) PersistentEntity(io.micronaut.data.model.PersistentEntity) CollectionUtils(io.micronaut.core.util.CollectionUtils) StringJoiner(java.util.StringJoiner) QueryBuilder(io.micronaut.data.model.query.builder.QueryBuilder) Repository(io.micronaut.data.annotation.Repository) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata) Blob(java.sql.Blob) Collections(java.util.Collections) Association(io.micronaut.data.model.Association) ArrayList(java.util.ArrayList) Objects(java.util.Objects) Annotation(java.lang.annotation.Annotation) MappingException(io.micronaut.data.exceptions.MappingException)

Aggregations

Join (io.micronaut.data.annotation.Join)3 Association (io.micronaut.data.model.Association)3 PersistentPropertyPath (io.micronaut.data.model.PersistentPropertyPath)3 AnnotationMetadata (io.micronaut.core.annotation.AnnotationMetadata)2 AnnotationValue (io.micronaut.core.annotation.AnnotationValue)2 Creator (io.micronaut.core.annotation.Creator)2 Experimental (io.micronaut.core.annotation.Experimental)2 NonNull (io.micronaut.core.annotation.NonNull)2 ArgumentUtils (io.micronaut.core.util.ArgumentUtils)2 ArrayUtils (io.micronaut.core.util.ArrayUtils)2 CollectionUtils (io.micronaut.core.util.CollectionUtils)2 StringUtils (io.micronaut.core.util.StringUtils)2 GeneratedValue (io.micronaut.data.annotation.GeneratedValue)2 AUTO (io.micronaut.data.annotation.GeneratedValue.Type.AUTO)2 IDENTITY (io.micronaut.data.annotation.GeneratedValue.Type.IDENTITY)2 SEQUENCE (io.micronaut.data.annotation.GeneratedValue.Type.SEQUENCE)2 UUID (io.micronaut.data.annotation.GeneratedValue.Type.UUID)2 Index (io.micronaut.data.annotation.Index)2 Indexes (io.micronaut.data.annotation.Indexes)2 MappedEntity (io.micronaut.data.annotation.MappedEntity)2