Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@
import com.querydsl.core.types.*;
import com.querydsl.core.types.OrderSpecifier.NullHandling;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.PathBuilder;
import com.querydsl.sql.SQLQuery;
import com.querydsl.sql.SQLQueryFactory;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.mapping.PropertyPath;
import org.springframework.data.querydsl.QSort;
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
import org.springframework.util.Assert;

import java.util.List;
Expand All @@ -36,11 +36,11 @@
public class Querydsl {

private final SQLQueryFactory sqlQueryFactory;
private final PathBuilder<?> builder;
private final RelationalPersistentEntity<?> entity;

public Querydsl(SQLQueryFactory sqlQueryFactory, PathBuilder<?> builder) {
public Querydsl(SQLQueryFactory sqlQueryFactory, RelationalPersistentEntity<?> entity) {
this.sqlQueryFactory = sqlQueryFactory;
this.builder = builder;
this.entity = entity;
}

public SQLQuery<?> createQuery() {
Expand Down Expand Up @@ -135,18 +135,9 @@ private Expression<?> buildOrderPropertyPathFrom(Order order) {

Assert.notNull(order, "Order must not be null!");

PropertyPath path = PropertyPath.from(order.getProperty(), builder.getType());
Expression<?> sortPropertyExpression = builder;
RelationalPersistentProperty persistentProperty = entity.getRequiredPersistentProperty(order.getProperty());
String columnName = persistentProperty.getColumnName().getReference();

while (path != null) {

sortPropertyExpression = !path.hasNext() && order.isIgnoreCase() && String.class.equals(path.getType()) //
? Expressions.stringPath((Path<?>) sortPropertyExpression, path.getSegment()).lower() //
: Expressions.path(path.getType(), (Path<?>) sortPropertyExpression, path.getSegment());

path = path.next();
}

return sortPropertyExpression;
return Expressions.stringPath(columnName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import com.infobip.spring.data.common.Querydsl;
import com.infobip.spring.data.common.QuerydslExpressionFactory;
import com.querydsl.core.types.ConstructorExpression;
import com.querydsl.core.types.dsl.PathBuilder;
import com.querydsl.sql.*;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.jdbc.core.convert.DataAccessStrategy;
Expand Down Expand Up @@ -88,7 +87,7 @@ private QuerydslJdbcPredicateExecutor<?> createQuerydslJdbcPredicateExecutor(Rep
ConstructorExpression<?> constructorExpression,
RelationalPathBase<?> path) {
RelationalPersistentEntity<?> entity = context.getRequiredPersistentEntity(metadata.getDomainType());
Querydsl querydsl = new Querydsl(sqlQueryFactory, new PathBuilder<>(path.getType(), path.getMetadata()));
Querydsl querydsl = new Querydsl(sqlQueryFactory, entity);
return getTargetRepositoryViaReflection(QuerydslJdbcPredicateExecutor.class,
entity,
converter,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.infobip.spring.data.jdbc.sorting;

import lombok.*;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;

@Value
@Table("sorting_entity")
public class SortingEntity {

@With
@Id
@Column("id")
private final Long id;

@Column("foo_bar")
private final String fooBar;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.infobip.spring.data.jdbc.sorting;

import com.infobip.spring.data.jdbc.QuerydslJdbcRepository;

public interface SortingEntityPagingRepository extends QuerydslJdbcRepository<SortingEntity, Long> {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.infobip.spring.data.jdbc.sorting;

import com.infobip.spring.data.jdbc.TestBase;
import lombok.AllArgsConstructor;
import org.junit.jupiter.api.Test;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.querydsl.QPageRequest;

import static com.infobip.spring.data.jdbc.sorting.QSortingEntity.sortingEntity;
import static org.assertj.core.api.BDDAssertions.then;

@AllArgsConstructor
public class SortingEntityPagingRepositoryTest extends TestBase {

private final SortingEntityPagingRepository repository;

@Test
void shouldFindByPage() {
// given
SortingEntity givenEntity = repository.save(new SortingEntity(null, "givenValue"));

// when
Page<SortingEntity> actual = repository.findAll(PageRequest.of(0, 1));

then(actual.getContent()).containsExactly(givenEntity);
}

@Test
void shouldSortUsingQSort() {
// given
SortingEntity givenEntityA = repository.save(new SortingEntity(null, "A"));
SortingEntity givenEntityC = repository.save(new SortingEntity(null, "C"));
SortingEntity givenEntityB = repository.save(new SortingEntity(null, "B"));

// when
Page<SortingEntity> actual = repository.findAll(QPageRequest.of(0, 5, sortingEntity.fooBar.desc()));

then(actual.getContent()).containsExactly(givenEntityC, givenEntityB, givenEntityA);
}

@Test
void shouldSortUsingSort() {
// given
SortingEntity givenEntityA = repository.save(new SortingEntity(null, "A"));
SortingEntity givenEntityC = repository.save(new SortingEntity(null, "C"));
SortingEntity givenEntityB = repository.save(new SortingEntity(null, "B"));

// when
Page<SortingEntity> actual = repository.findAll(PageRequest.of(0, 5, Sort.by(Order.desc("fooBar"))));

then(actual.getContent()).containsExactly(givenEntityC, givenEntityB, givenEntityA);
}

@Test
void shouldSortUsingQSortCombinedWithPredicate() {
// given
SortingEntity givenEntityA = repository.save(new SortingEntity(null, "1A"));
SortingEntity givenEntityC = repository.save(new SortingEntity(null, "1C"));
SortingEntity givenEntityB = repository.save(new SortingEntity(null, "1B"));
SortingEntity otherEntity = repository.save(new SortingEntity(null, "2"));

// when
Page<SortingEntity> actual = repository.findAll(
sortingEntity.fooBar.startsWith("1"),
// does not work because generated classes in this project uses different naming strategy then is used in this project
Comment thread
dirkluijk marked this conversation as resolved.
Outdated
QPageRequest.of(0, 5, sortingEntity.fooBar.desc())
);

then(actual.getContent()).containsExactly(givenEntityC, givenEntityB, givenEntityA);
}

@Test
void shouldSortUsingSortCombinedWithPredicate() {
// given
SortingEntity givenEntityA = repository.save(new SortingEntity(null, "1A"));
SortingEntity givenEntityC = repository.save(new SortingEntity(null, "1C"));
SortingEntity givenEntityB = repository.save(new SortingEntity(null, "1B"));
SortingEntity otherEntity = repository.save(new SortingEntity(null, "2"));

// when
Page<SortingEntity> actual = repository.findAll(
sortingEntity.fooBar.startsWith("1"),
PageRequest.of(0, 5, Sort.by(Order.desc("fooBar")))
);

then(actual.getContent()).containsExactly(givenEntityC, givenEntityB, givenEntityA);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,9 @@ CREATE TABLE PagingEntity (
Value NVARCHAR(20),
CONSTRAINT PK_PagingEntity PRIMARY KEY (Id),
);

CREATE TABLE sorting_entity (
id BIGINT IDENTITY,
foo_bar NVARCHAR(20),
CONSTRAINT PK_sorting_entity PRIMARY KEY (id),
);
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@
import com.infobip.spring.data.common.Querydsl;
import com.infobip.spring.data.common.QuerydslExpressionFactory;
import com.querydsl.core.types.ConstructorExpression;
import com.querydsl.core.types.dsl.PathBuilder;
import com.querydsl.sql.*;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.r2dbc.convert.R2dbcConverter;
import org.springframework.data.r2dbc.core.R2dbcEntityOperations;
import org.springframework.data.r2dbc.repository.support.R2dbcRepositoryFactory;
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryComposition;
import org.springframework.data.repository.core.support.RepositoryFragment;
Expand Down Expand Up @@ -85,9 +88,15 @@ private RepositoryFragment<Object> createSimpleQuerydslR2dbcFragment(RelationalP
return RepositoryFragment.implemented(simpleJPAQuerydslFragment);
}

@SuppressWarnings("unchecked")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be moved above line 97 to minimize the scope (since it's merged I'll do it on master)

private RepositoryFragment<Object> createQuerydslJdbcPredicateExecutor(ConstructorExpression<?> constructorExpression,
RelationalPathBase<?> path) {
Querydsl querydsl = new Querydsl(sqlQueryFactory, new PathBuilder<>(path.getType(), path.getMetadata()));


MappingContext<? extends RelationalPersistentEntity<?>, ? extends RelationalPersistentProperty> context = converter.getMappingContext();
RelationalPersistentEntity<?> entity = context.getRequiredPersistentEntity(constructorExpression.getType());

Querydsl querydsl = new Querydsl(sqlQueryFactory, entity);
Object querydslJdbcPredicateExecutor = getTargetRepositoryViaReflection(
ReactiveQuerydslR2dbcPredicateExecutor.class,
constructorExpression,
Expand Down