Skip to content

Commit

Permalink
[#1851] Disallow repository sorting by anything other than entity or …
Browse files Browse the repository at this point in the history
…entity view attribute paths
  • Loading branch information
beikov committed Jan 10, 2024
1 parent b440469 commit 0b64393
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@

package com.blazebit.persistence.spring.data.base;

import jakarta.persistence.metamodel.Attribute;
import jakarta.persistence.metamodel.ManagedType;

import com.blazebit.persistence.FullQueryBuilder;
import com.blazebit.persistence.parser.expression.ExpressionFactory;
import com.blazebit.persistence.parser.expression.PathElementExpression;
import com.blazebit.persistence.parser.expression.PathExpression;
import com.blazebit.persistence.view.EntityViewManager;
import com.blazebit.persistence.view.metamodel.ManagedViewType;
import com.blazebit.persistence.view.metamodel.MethodAttribute;
Expand Down Expand Up @@ -82,6 +88,24 @@ public static void applySort(EntityViewManager evm, Class<?> entityViewClass, Fu
for (Sort.Order order : sort) {
String entityViewAttributeAlias;
if ((entityViewAttributeAlias = EntityViewSortUtil.resolveViewAttributeSelectAlias(viewType, order.getProperty())) == null) {
PathExpression pathExpression;
try {
pathExpression = cb.getService(ExpressionFactory.class).createPathExpression(order.getProperty());
} catch (RuntimeException ex) {
throw new IllegalArgumentException("Sort order [" + order.getProperty() + "] is not resolvable to a path expression.", ex);
}
jakarta.persistence.metamodel.Type<?> resultType = cb.getMetamodel().entity(viewType.getEntityClass());
for (PathElementExpression expression : pathExpression.getExpressions()) {
if (!(resultType instanceof ManagedType<?>)) {
throw new IllegalArgumentException("Sort order [" + order.getProperty() + "] is not resolvable to a valid path expression, because the type [" + resultType.getJavaType().getName() + "] can't be de-referenced.");
}
ManagedType<?> managedType = (ManagedType<?>) resultType;
Attribute<?, ?> attribute = managedType.getAttribute(expression.toString());
if (!(attribute instanceof jakarta.persistence.metamodel.SingularAttribute<?, ?>)) {
throw new IllegalArgumentException("Sort order [" + order.getProperty() + "] is not resolvable to a valid path expression, because the type [" + resultType.getJavaType().getName() + "] does not contain a singular attribute named [" + expression + "].");
}
resultType = ( (jakarta.persistence.metamodel.SingularAttribute<?, ?>) attribute ).getType();
}
cb.orderBy(order.getProperty(), order.isAscending(), order.getNullHandling() == Sort.NullHandling.NULLS_FIRST);
} else {
cb.orderBy(entityViewAttributeAlias, order.isAscending(), order.getNullHandling() == Sort.NullHandling.NULLS_FIRST);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@

package com.blazebit.persistence.spring.data.base;

import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.ManagedType;

import com.blazebit.persistence.FullQueryBuilder;
import com.blazebit.persistence.parser.expression.ExpressionFactory;
import com.blazebit.persistence.parser.expression.PathElementExpression;
import com.blazebit.persistence.parser.expression.PathExpression;
import com.blazebit.persistence.view.EntityViewManager;
import com.blazebit.persistence.view.metamodel.ManagedViewType;
import com.blazebit.persistence.view.metamodel.MethodAttribute;
Expand Down Expand Up @@ -81,6 +87,24 @@ public static void applySort(EntityViewManager evm, Class<?> entityViewClass, Fu
for (Sort.Order order : sort) {
String entityViewAttributeAlias;
if ((entityViewAttributeAlias = EntityViewSortUtil.resolveViewAttributeSelectAlias(viewType, order.getProperty())) == null) {
PathExpression pathExpression;
try {
pathExpression = cb.getService(ExpressionFactory.class).createPathExpression(order.getProperty());
} catch (RuntimeException ex) {
throw new IllegalArgumentException("Sort order [" + order.getProperty() + "] is not resolvable to a path expression.", ex);
}
javax.persistence.metamodel.Type<?> resultType = cb.getMetamodel().entity(viewType.getEntityClass());
for (PathElementExpression expression : pathExpression.getExpressions()) {
if (!(resultType instanceof ManagedType<?>)) {
throw new IllegalArgumentException("Sort order [" + order.getProperty() + "] is not resolvable to a valid path expression, because the type [" + resultType.getJavaType().getName() + "] can't be de-referenced.");
}
ManagedType<?> managedType = (ManagedType<?>) resultType;
Attribute<?, ?> attribute = managedType.getAttribute(expression.toString());
if (!(attribute instanceof javax.persistence.metamodel.SingularAttribute<?, ?>)) {
throw new IllegalArgumentException("Sort order [" + order.getProperty() + "] is not resolvable to a valid path expression, because the type [" + resultType.getJavaType().getName() + "] does not contain a singular attribute named [" + expression + "].");
}
resultType = ( (javax.persistence.metamodel.SingularAttribute<?, ?>) attribute ).getType();
}
cb.orderBy(order.getProperty(), order.isAscending(), order.getNullHandling() == Sort.NullHandling.NULLS_FIRST);
} else {
cb.orderBy(entityViewAttributeAlias, order.isAscending(), order.getNullHandling() == Sort.NullHandling.NULLS_FIRST);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
import com.blazebit.persistence.view.EntityViewManager;
import com.blazebit.persistence.view.EntityViewSetting;
import com.blazebit.persistence.view.Sorters;

import org.junit.Assert;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
Expand Down Expand Up @@ -879,6 +881,21 @@ public void testFindByEnum() {
assertEquals(1, elementCount);
}

@Test
public void testSortByExpression() {
// Given
final Document d1 = createDocument("D1", "test", 0, null);

// When
try {
readOnlyDocumentRepository.findAll(Sort.of(new org.springframework.data.domain.Sort.Order(null, "1")));
Assert.fail("Should fail because '1' is not a valid property to sort by");
} catch (RuntimeException ex) {
// Then
assertTrue( ex.getMessage().contains( "Sort order [1] is not resolvable to a path expression" ) );
}
}

private Pageable unpaged() {
try {
Method unpaged = Class.forName("org.springframework.data.domain.Pageable").getMethod("unpaged");
Expand Down

0 comments on commit 0b64393

Please sign in to comment.