Предположим, у вас есть следующая сущность:

@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;
            }
        }
    }
}

Если мой GameRepository является PagingAndSortingRepository, как я могу получить страницу результатов, отсортированных по свойству status?

Сейчас я получаю:

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

Это я могу понять, поскольку status действительно не является атрибутом JPA. Это можно обойти?

(Я использую Hibernate внизу, так что все, что касается Hibernate, тоже нормально)

6
Wim Deblauwe 10 Май 2016 в 16:27

2 ответа

Лучший ответ

Проблема в том, что сортировка PageRequest Spring Data выполняется на уровне базы данных путем формирования предложения ORDER BY.

Вы можете создать столбец @Formula, например.

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

Тогда можно будет использовать новый столбец в порядке сортировки, поскольку все, что вы напишете в формуле, будет передано в предложение ORDER BY.

10
ike3 10 Май 2016 в 13:39

Использовать аннотацию @Formula

Пример: tickePrice = totalAmount / admissions.

@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;
}

Для сортировки по этому столбцу требуется наличие результата в столбце.

GET example-url?size=25&page=0&sort=ticketPrice,ASC
1
tsunllly 4 Май 2020 в 21:26