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);
}
}
}
}
}
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 + ")";
}
}
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);
}
Aggregations