use of io.micronaut.data.model.jpa.criteria.impl.AbstractPersistentEntityCriteriaUpdate 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;
}
};
}
use of io.micronaut.data.model.jpa.criteria.impl.AbstractPersistentEntityCriteriaUpdate in project micronaut-data by micronaut-projects.
the class UpdateCriteriaMethodMatch method build.
@Override
protected MethodMatchInfo build(MethodMatchContext matchContext) {
MethodMatchSourcePersistentEntityCriteriaBuilderImpl cb = new MethodMatchSourcePersistentEntityCriteriaBuilderImpl(matchContext);
PersistentEntityCriteriaUpdate<Object> criteriaQuery = cb.createCriteriaUpdate(null);
apply(matchContext, criteriaQuery.from(matchContext.getRootEntity()), criteriaQuery, cb);
Map.Entry<ClassElement, Class<? extends DataInterceptor>> entry = resolveReturnTypeAndInterceptor(matchContext);
ClassElement resultType = entry.getKey();
Class<? extends DataInterceptor> interceptorType = entry.getValue();
AbstractPersistentEntityCriteriaUpdate<?> criteriaUpdate = (AbstractPersistentEntityCriteriaUpdate<?>) criteriaQuery;
boolean optimisticLock = criteriaUpdate.hasVersionRestriction();
final AnnotationMetadataHierarchy annotationMetadataHierarchy = new AnnotationMetadataHierarchy(matchContext.getRepositoryClass().getAnnotationMetadata(), matchContext.getAnnotationMetadata());
QueryBuilder queryBuilder = matchContext.getQueryBuilder();
Map<String, Object> propertiesToUpdate = criteriaUpdate.getUpdateValues();
QueryModel queryModel = ((AbstractPersistentEntityCriteriaUpdate) criteriaQuery).getQueryModel();
QueryResult queryResult = queryBuilder.buildUpdate(annotationMetadataHierarchy, queryModel, propertiesToUpdate);
return new MethodMatchInfo(DataMethod.OperationType.UPDATE, resultType, getInterceptorElement(matchContext, interceptorType)).optimisticLock(optimisticLock).queryResult(queryResult);
}
use of io.micronaut.data.model.jpa.criteria.impl.AbstractPersistentEntityCriteriaUpdate in project micronaut-data by micronaut-projects.
the class UpdateCriteriaMethodMatch method apply.
/**
* Apply query match.
*
* @param matchContext The match context
* @param root The root
* @param query The query
* @param cb The criteria builder
* @param <T> The entity type
*/
protected <T> void apply(MethodMatchContext matchContext, PersistentEntityRoot<T> root, PersistentEntityCriteriaUpdate<T> query, SourcePersistentEntityCriteriaBuilder cb) {
String querySequence = matcher.group(3);
if (matcher.group(2).endsWith("By")) {
applyPredicates(querySequence, matchContext.getParameters(), root, query, cb);
} else {
applyPredicates(matchContext.getParametersNotInRole(), root, query, cb);
}
if (query.getRestriction() == null) {
throw new MatchFailedException("Cannot implement batch update operation that doesn't perform a query");
}
SourcePersistentEntity entity = matchContext.getRootEntity();
addPropertiesToUpdate(matchContext, root, query, cb);
// Add updatable auto-populated parameters
entity.getPersistentProperties().stream().filter(p -> p != null && p.findAnnotation(AutoPopulated.class).map(ap -> ap.getRequiredValue(AutoPopulated.UPDATEABLE, Boolean.class)).orElse(false)).forEach(p -> query.set(p.getName(), cb.parameter((ParameterElement) null)));
if (entity.getVersion() != null) {
if (((AbstractPersistentEntityCriteriaUpdate<T>) query).hasVersionRestriction()) {
query.set(entity.getVersion().getName(), cb.parameter((ParameterElement) null));
}
}
if (((AbstractPersistentEntityCriteriaUpdate<T>) query).getUpdateValues().isEmpty()) {
throw new MatchFailedException("At least one parameter required to update");
}
}
Aggregations