简体   繁体   English

Spring Data JPA - 是否可以对计算属性进行排序?

[英]Spring Data JPA - Is it possible to sort on a calculated property?

Suppose you have the following Entity:假设您有以下实体:

@Entity
public class Game {

    @Id
    @GeneratedValue
    private Integer id;

    private String name;

    private Calendar startTime;
    private int durationInSeconds;

    public GameStatus getStatus() {
        if( startTime.after(Calendar.getInstance()))
        {
            return GameStatus.SCHEDULED;
        } else {
            Calendar endTime = Calendar.getInstance();
            endTime.setTime(startTime.getTime());
            endTime.roll(Calendar.SECOND, durationInSeconds);

            if( endTime.after(Calendar.getInstance())) {
                return GameStatus.OPEN_FOR_PLAY;
            }
            else {
                return GameStatus.FINISHED;
            }
        }
    }
}

If my GameRepository is a PagingAndSortingRepository , how can I get a page of results, sorted by the status property?如果我的GameRepositoryPagingAndSortingRepository ,我如何获得按status属性排序的结果页面?

I currently get:我目前得到:

java.lang.IllegalArgumentException: Unable to locate Attribute  with the the 
given name [status] on this ManagedType [org.test.model.Game]

Which I can understand since status is indeed no JPA attribute.我可以理解,因为status确实没有 JPA 属性。 Is there a way around this?有没有办法解决这个问题?

(I am using Hibernate underneath, so anything Hibernate specific is also ok) (我在下面使用 Hibernate,所以任何 Hibernate 特定的东西也可以)

The problem is that Spring Data's PageRequest sort is done on the database layer by forming the ORDER BY clause.问题是 Spring Data 的 PageRequest 排序是通过形成 ORDER BY 子句在数据库层完成的。

You could create a @Formula column, eg您可以创建一个@Formula 列,例如

@Entity
public class Game {
...
     // rewrite your logic here in HQL
     @Formula("case when startTime >= endTime then 'FINISHED' ... end")
     private String status;

Then it will be possible to use the new column in sort order as everything you write in the formula will be passed to ORDER BY clause.然后可以按排序顺序使用新列,因为您在公式中编写的所有内容都将传递给 ORDER BY 子句。

Use annotation @Formula使用注解@Formula

Example: tickePrice = totalAmount / admissions示例:ticketPrice = totalAmount / 入场人数

@Entity
public class Event {
...
   // To avoid division by 0, and setting to 0 if admissions is 0 
   @Formula(value = "coalesce(totalAmount / NULLIF(admissions, 0), 0)")
   private Double ticketPrice;
}

To sort by this column is required to be present as a column result.按此列排序需要作为列结果存在。

GET example-url?size=25&page=0&sort=ticketPrice,ASC

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM