QueryDSL sorting not working with Spring Data

2019-02-26 05:17发布

I am currently using JpaSort with Spring Data commons 1.9.1 and Spring JPA 1.7.1. I need to use QueryDSL because JPA does not allow defining the sort for null values.

This is my Repository

public interface DatasheetRepository extends JpaRepository<Datasheet, Long>, JpaSpecificationExecutor<Datasheet>

I am doing this in my Controller:

Page<Datasheet> page = m_datasheetRepository.findAll( new PageRequest( pageNumber, pageSize, createSortForDatasheets() ) );

This is what I had with JPA:

private Sort createSortForDatasheets()
{
    // First sort on the component type name, then on the subtype name
    return new JpaSort( JpaSort.path( Datasheet_.componentSubtype ).dot( ComponentSubtype_.componentType ).dot( ComponentType_.name ) )
            .and( new JpaSort( JpaSort.path( Datasheet_.componentSubtype ).dot( ComponentSubtype_.name ) ) );
}

This is what I have changed it to for QueryDSL:

private Sort createSortForDatasheets()
{
    return new QSort( new OrderSpecifier<>( Order.ASC, QDatasheet.datasheet.componentSubtype.componentType.name,OrderSpecifier.NullHandling.NullsLast ) )
            .and( new OrderSpecifier<>( Order.ASC, QDatasheet.datasheet.componentSubtype.name, OrderSpecifier.NullHandling.NullsLast ) );
}

However, nothing seems to get sorted. I have enabled DEBUG logging and I see this:

Rendered criteria query -> select generatedAlias0 from Datasheet as generatedAlias0 order by generatedAlias0.name asc, generatedAlias0.name asc

If I change it to:

private Sort createSortForDatasheets()
{
    return new QSort(QDatasheet.datasheet.name.desc());
}

Then the sorting by the name of my "Datasheet" type in reverse order does work.

This is my "Datasheet" entity:

@Entity
public class Datasheet
{
// ------------------------------ FIELDS ------------------------------

    @Id
    @GeneratedValue
    private long id;

    @Column(unique = true)
    private String name;
    private String description;

    @ManyToOne
    private ComponentSubtype componentSubtype;

    @OneToMany(cascade = CascadeType.REMOVE)
    private Set<DatasheetDocument> documents;

And this is "ComponentSubtype":

@Entity
public class ComponentSubtype
{
    @Id
    @GeneratedValue()
    private long id;

    private String name;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_id",insertable=false,updatable=false)
    private ComponentType componentType;

UPDATE:

If I change the createSortForDatasheets to this:

private Sort createSortForDatasheets()
{
    return new QSort( new OrderSpecifier<>( Order.ASC, QComponentType.componentType.id, OrderSpecifier.NullHandling.NullsLast ) );
}

Then, the logging shows:

Rendered criteria query -> select generatedAlias0 from Datasheet as generatedAlias0 order by generatedAlias0.id asc

Notice how the id of the "Datasheet" is used, and not the id of "ComponentType".

1条回答
乱世女痞
2楼-- · 2019-02-26 05:52

It looks like Spring Data bug. I filed an issue for it https://jira.spring.io/browse/DATACMNS-621

查看更多
登录 后发表回答