Skip to content

Commit

Permalink
Correct multi property order path
Browse files Browse the repository at this point in the history
  • Loading branch information
dstepanov committed Jan 29, 2025
1 parent 8561918 commit 8a67190
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ package io.micronaut.data.jdbc.h2
import io.micronaut.core.annotation.Introspected
import io.micronaut.data.annotation.*
import io.micronaut.data.jdbc.annotation.JdbcRepository
import io.micronaut.data.model.Page
import io.micronaut.data.model.Pageable
import io.micronaut.data.model.Sort
import io.micronaut.data.model.query.builder.sql.Dialect
import io.micronaut.data.repository.CrudRepository
Expand Down Expand Up @@ -52,6 +54,9 @@ class H2EmbeddedIdSpec extends Specification {
}

void "test CRUD"() {
given:
repository.deleteAll()

when:
ShipmentId id = new ShipmentId("a", "b")
repository.save(new Shipment(id, "test"))
Expand Down Expand Up @@ -156,6 +161,31 @@ class H2EmbeddedIdSpec extends Specification {
then:"The entities where deleted"
repository.count() == 0
}

void "test criteria order of embedded"() {
given:
repository.deleteAll()
when:
ShipmentId id = new ShipmentId("a", "b")
repository.save(new Shipment(id, "test"))

ShipmentId id2 = new ShipmentId("c", "d")
repository.save(new Shipment(id2, "test2"))

ShipmentId id3 = new ShipmentId("e", "f")
repository.save(new Shipment(id3, "test3"))

ShipmentId id4 = new ShipmentId("g", "h")
repository.save(new Shipment(id4, "test4"))

Sort.Order.Direction sortDirection = Sort.Order.Direction.ASC;
Pageable pageable = Pageable.UNPAGED.order(new Sort.Order("shipmentId.city", sortDirection, false));
def page = repository.findAll(pageable)

then:
page.totalSize == 4
page.content[0].shipmentId.city == "b"
}
}

@Entity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,18 @@ package io.micronaut.data.jdbc.h2.embeddedAssociation

import io.micronaut.context.ApplicationContext
import io.micronaut.data.annotation.*
import io.micronaut.data.annotation.repeatable.JoinSpecifications
import io.micronaut.data.jdbc.annotation.JdbcRepository
import io.micronaut.data.jdbc.h2.H2DBProperties
import io.micronaut.data.jdbc.h2.H2TestPropertyProvider
import io.micronaut.data.model.Page
import io.micronaut.data.model.Pageable
import io.micronaut.data.model.Sort
import io.micronaut.data.model.query.builder.sql.Dialect
import io.micronaut.data.repository.CrudRepository
import io.micronaut.data.repository.jpa.JpaSpecificationExecutor
import io.micronaut.data.repository.jpa.criteria.PredicateSpecification
import io.micronaut.data.tck.entities.Order
import io.micronaut.test.extensions.spock.annotation.MicronautTest
import spock.lang.AutoCleanup
import spock.lang.Shared
Expand Down Expand Up @@ -64,6 +71,11 @@ class EmbeddedAssociationJoinSpec extends Specification implements H2TestPropert
when:
mainEntityRepository.save(e)
e = mainEntityRepository.findById(e.id).get()
Sort.Order.Direction sortDirection = Sort.Order.Direction.ASC;
Pageable pageable = Pageable.UNPAGED.order(new Sort.Order("child.name", sortDirection, false));
mainEntityRepository.findAll(pageable).totalPages == 1
PredicateSpecification<Order> predicate = null
mainEntityRepository.findAllByCriteria(predicate, pageable).totalPages == 1
then:
e.id
e.assoc.size() == 2
Expand Down Expand Up @@ -113,12 +125,18 @@ class EmbeddedAssociationJoinSpec extends Specification implements H2TestPropert
}

@JdbcRepository(dialect = Dialect.H2)
interface MainEntityRepository extends CrudRepository<MainEntity, Long> {
interface MainEntityRepository extends CrudRepository<MainEntity, Long>, JpaSpecificationExecutor<MainEntity> {

@Join(value = "assoc", type = Join.Type.FETCH)
@Join(value = "em.assoc", type = Join.Type.FETCH)
@Override
Optional<MainEntity> findById(Long aLong)

@JoinSpecifications(@Join(value = "child", type = Join.Type.LEFT_FETCH))
Page<MainEntity> findAll(Pageable pageable)

@JoinSpecifications(@Join(value = "child", type = Join.Type.LEFT_FETCH))
Page<MainEntity> findAllByCriteria(PredicateSpecification<Order> spec, Pageable pageable)
}

@JdbcRepository(dialect = Dialect.H2)
Expand Down Expand Up @@ -199,4 +217,4 @@ class MainEntityAssociation {
@GeneratedValue
Long id
String name
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,50 @@ package io.micronaut.data.processor.visitors
import io.micronaut.data.annotation.Query
import io.micronaut.data.tck.entities.Company

import static io.micronaut.data.processor.visitors.TestUtils.getQuery

class OrderBySpec extends AbstractDataSpec {

void "test sort embedded"() {
given:
def repository = buildRepository('test.TestRepository', '''
import io.micronaut.data.annotation.Repository;
import io.micronaut.data.repository.GenericRepository;
import io.micronaut.data.tck.entities.Shipment;
import io.micronaut.data.tck.entities.ShipmentDto;
import io.micronaut.data.tck.entities.ShipmentId;
@Repository
interface TestRepository extends GenericRepository<Shipment, ShipmentId> {
List<Shipment> findAllOrderByShipmentIdCity();
}
''')
when:
def queryFindByText = getQuery(repository.getRequiredMethod("findAllOrderByShipmentIdCity"))
then:
queryFindByText == 'SELECT shipment_ FROM io.micronaut.data.tck.entities.Shipment AS shipment_ ORDER BY shipment_.shipmentId.city ASC'
}

void "test sort embedded JDBC"() {
given:
def repository = buildRepository('test.TestRepository', '''
import io.micronaut.data.jdbc.annotation.JdbcRepository;
import io.micronaut.data.model.query.builder.sql.Dialect;
import io.micronaut.data.repository.GenericRepository;
import io.micronaut.data.tck.entities.Shipment;
import io.micronaut.data.tck.entities.ShipmentDto;
import io.micronaut.data.tck.entities.ShipmentId;
@JdbcRepository(dialect = Dialect.POSTGRES)
interface TestRepository extends GenericRepository<Shipment, ShipmentId> {
List<Shipment> findAllOrderByShipmentIdCity();
}
''')
when:
def queryFindByText = getQuery(repository.getRequiredMethod("findAllOrderByShipmentIdCity"))
then:
queryFindByText == 'SELECT shipment_."sp_country",shipment_."sp_city",shipment_."field" FROM "Shipment1" shipment_ ORDER BY shipment_."sp_city" ASC'
}

void "test order by date created"() {
given:
def repository = buildRepository('test.MyInterface', """
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
import jakarta.persistence.criteria.Selection;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
Expand Down Expand Up @@ -376,7 +377,16 @@ private <K> CriteriaQuery<Tuple> createSelectIdsCriteriaQuery(MethodInvocationCo
selection.add(getIdExpression(root));
// We need to select all ordered properties from ORDER BY for DISTINCT to work properly
for (Sort.Order order : sort.getOrderBy()) {
selection.add(root.get(order.getProperty()));
Path<Object> path = null;
for (Iterator<String> iterator = StringUtils.splitOmitEmptyStrings(order.getProperty(), '.').iterator(); iterator.hasNext(); ) {
String next = iterator.next();
if (iterator.hasNext()) {
path = root.join(next);
} else {
path = root.get(next);
}
}
selection.add(path);
}
criteriaQuery.multiselect(selection).distinct(true);
if (specification != null) {
Expand Down Expand Up @@ -577,8 +587,13 @@ private List<Order> getOrders(Sort sort, Root<?> root, CriteriaBuilder cb) {
List<Order> orders = new ArrayList<>();
for (Sort.Order order : sort.getOrderBy()) {
Path<?> path = root;
for (String property : StringUtils.splitOmitEmptyStrings(order.getProperty(), '.')) {
path = path.get(property);
for (Iterator<String> iterator = StringUtils.splitOmitEmptyStrings(order.getProperty(), '.').iterator(); iterator.hasNext(); ) {
String next = iterator.next();
if (iterator.hasNext()) {
path = root.join(next);
} else {
path = root.get(next);
}
}
Expression<?> expression = order.isIgnoreCase() ? cb.lower(path.type().as(String.class)) : path;
orders.add(order.isAscending() ? cb.asc(expression) : cb.desc(expression));
Expand Down

0 comments on commit 8a67190

Please sign in to comment.