use of io.micronaut.data.model.Association in project micronaut-data by micronaut-projects.
the class AbstractSqlLikeQueryBuilder method handleAssociationCriteria.
private void handleAssociationCriteria(CriteriaContext ctx, AssociationQuery associationQuery) {
QueryState queryState = ctx.getQueryState();
Association association = associationQuery.getAssociation();
if (association == null) {
return;
}
// Join should be applied in `findProperty` only in cases when it's needed; we don't need to join to access the identity
String associationPath = associationQuery.getPath();
CriteriaContext associatedContext = new CriteriaContext() {
@Override
public String getCurrentTableAlias() {
return ctx.getCurrentTableAlias();
}
@Override
public QueryState getQueryState() {
return ctx.getQueryState();
}
@Override
public PersistentEntity getPersistentEntity() {
return ctx.getPersistentEntity();
}
@Override
public QueryPropertyPath getRequiredProperty(String name, Class<?> criterionClazz) {
if (StringUtils.isNotEmpty(associationPath)) {
name = associationPath + DOT + name;
}
return findPropertyInternal(queryState, getPersistentEntity(), getCurrentTableAlias(), name, criterionClazz);
}
};
handleJunction(associatedContext, associationQuery.getCriteria());
}
use of io.micronaut.data.model.Association in project micronaut-data by micronaut-projects.
the class JpaQueryBuilder method buildJoin.
@Override
protected String[] buildJoin(String alias, JoinPath joinPath, String joinType, StringBuilder target, Map<String, String> appliedJoinPaths, QueryState queryState) {
Association[] associationPath = joinPath.getAssociationPath();
String[] joinAliases;
if (ArrayUtils.isEmpty(associationPath)) {
throw new IllegalArgumentException("Invalid association path [" + joinPath.getPath() + "]");
}
List<Association> joinAssociationsPath = new ArrayList<>(associationPath.length);
joinAliases = new String[associationPath.length];
StringJoiner pathSoFar = new StringJoiner(".");
List<String> aliases = new ArrayList<>();
for (int i = 0; i < associationPath.length; i++) {
Association association = associationPath[i];
pathSoFar.add(association.getName());
if (association instanceof Embedded) {
joinAssociationsPath.add(association);
continue;
}
String currentPath = pathSoFar.toString();
String existingAlias = appliedJoinPaths.get(currentPath);
if (existingAlias != null) {
joinAliases[i] = existingAlias;
aliases.add(existingAlias);
} else {
int finalI = i;
JoinPath joinPathToUse = queryState.getQueryModel().getJoinPath(currentPath).orElseGet(() -> new JoinPath(currentPath, Arrays.copyOfRange(associationPath, 0, finalI + 1), joinPath.getJoinType(), joinPath.getAlias().orElse(null)));
String currentAlias = getAliasName(joinPathToUse);
joinAliases[i] = currentAlias;
String lastJoinAlias = aliases.isEmpty() ? alias : CollectionUtils.last(aliases);
target.append(joinType).append(lastJoinAlias).append(DOT).append(association.getName()).append(SPACE).append(joinAliases[i]);
aliases.add(currentAlias);
}
joinAssociationsPath.clear();
}
return joinAliases;
}
use of io.micronaut.data.model.Association in project micronaut-data by micronaut-projects.
the class NamingStrategy method mappedJoinTableColumn.
default String mappedJoinTableColumn(PersistentEntity associated, List<Association> associations, PersistentProperty property) {
StringBuilder sb = new StringBuilder();
sb.append(associated.getDecapitalizedName());
for (Association association : associations) {
sb.append(NameUtils.capitalize(association.getName()));
}
if (associations.isEmpty()) {
sb.append(getForeignKeySuffix());
} else {
sb.append(NameUtils.capitalize(property.getName()));
}
return mappedName(sb.toString());
}
use of io.micronaut.data.model.Association in project micronaut-data by micronaut-projects.
the class QueryParameter method asStringPath.
private String[] asStringPath(List<Association> associations, PersistentProperty property) {
if (associations.isEmpty()) {
return new String[] { property.getName() };
}
List<String> path = new ArrayList<>(associations.size() + 1);
for (Association association : associations) {
path.add(association.getName());
}
path.add(property.getName());
return path.toArray(new String[0]);
}
use of io.micronaut.data.model.Association in project micronaut-data by micronaut-projects.
the class UpdateMethodMatcher method entityUpdate.
private UpdateCriteriaMethodMatch entityUpdate(java.util.regex.Matcher matcher, ParameterElement entityParameter, ParameterElement entitiesParameter) {
return new UpdateCriteriaMethodMatch(matcher) {
ParameterElement entityParam = entityParameter == null ? entitiesParameter : entityParameter;
@Override
protected <T> void applyPredicates(List<ParameterElement> parameters, PersistentEntityRoot<T> root, PersistentEntityCriteriaUpdate<T> query, SourcePersistentEntityCriteriaBuilder cb) {
final SourcePersistentEntity rootEntity = (SourcePersistentEntity) root.getPersistentEntity();
Predicate predicate;
if (rootEntity.getVersion() != null) {
predicate = cb.and(cb.equal(root.id(), cb.entityPropertyParameter(entityParam)), cb.equal(root.version(), cb.entityPropertyParameter(entityParam)));
} else {
predicate = cb.equal(root.id(), cb.entityPropertyParameter(entityParam));
}
query.where(predicate);
}
@Override
protected <T> void addPropertiesToUpdate(MethodMatchContext matchContext, PersistentEntityRoot<T> root, PersistentEntityCriteriaUpdate<T> query, SourcePersistentEntityCriteriaBuilder cb) {
final SourcePersistentEntity rootEntity = matchContext.getRootEntity();
Stream.concat(rootEntity.getPersistentProperties().stream(), Stream.of(rootEntity.getVersion())).filter(p -> p != null && !((p instanceof Association) && ((Association) p).isForeignKey()) && !p.isGenerated() && p.findAnnotation(AutoPopulated.class).map(ap -> ap.getRequiredValue(AutoPopulated.UPDATEABLE, Boolean.class)).orElse(true)).forEach(p -> query.set(p.getName(), cb.entityPropertyParameter(entityParam)));
if (((AbstractPersistentEntityCriteriaUpdate<T>) query).getUpdateValues().isEmpty()) {
// Workaround for only ID entities
query.set(rootEntity.getIdentity().getName(), cb.entityPropertyParameter(entityParam));
}
}
@Override
protected boolean supportedByImplicitQueries() {
return true;
}
@Override
protected Map.Entry<ClassElement, Class<? extends DataInterceptor>> resolveReturnTypeAndInterceptor(MethodMatchContext matchContext) {
Map.Entry<ClassElement, Class<? extends DataInterceptor>> e = super.resolveReturnTypeAndInterceptor(matchContext);
ClassElement returnType = e.getKey();
if (returnType != null && !TypeUtils.isVoid(returnType) && !TypeUtils.isNumber(returnType) && !returnType.hasStereotype(MappedEntity.class) && !(TypeUtils.isReactiveOrFuture(matchContext.getReturnType()) && TypeUtils.isObjectClass(returnType))) {
throw new MatchFailedException("Cannot implement update method for specified return type: " + returnType.getName());
}
return e;
}
@Override
protected ParameterElement getEntityParameter() {
return entityParameter;
}
@Override
protected ParameterElement getEntitiesParameter() {
return entitiesParameter;
}
};
}
Aggregations