'select count(*) from' 在 spring jpa native query 使用分页时被 'select count(where)' 替换

'select count(*) from' is replaced by 'select count(where)' in spring jpa native query when using pagination

我在 @Query 注释内的 JPA 存储库中使用本机查询

    @Query(value = " select * from message where id in(select if(coalesce(a.maxId,0)>coalesce(b.maxId,0), a.maxId, b.maxId) maxId from (select from_number, to_number, " +
         " max(id) maxId,direction,type from message where direction='INCOMING' group by from_number, to_number having sum(type= :type)) as a " +
         " left join ( select from_number, to_number, max(id) maxId, direction, type from message where direction = 'OUTGOING' and schedule_id is null " +
         " group by from_number, to_number) as b on a.from_number=b.to_number and a.to_number=b.from_number) order by generated_time desc ", nativeQuery = true)
    Page<Message> getLatestMessageFromThread(@Param("type") String type, Pageable page);

问题是当我执行这个查询时出现语法错误。当我检查日志时,它显示查询中对总消息进行计数的查询如下所示

    select count(where) from message where id in(select if(coalesce(a.maxId,0)>coalesce(b.maxId,0), 
    a.maxId, b.maxId) maxId from (select from_number, to_number, max(id) maxId,direction,type from 
    message where direction='INCOMING' group by from_number, to_number having sum(type= 'REVIEW')) 
    as a left join ( select from_number, to_number, max(id) maxId, direction, type from message 
    where direction = 'OUTGOING' and schedule_id is null group by from_number, to_number) as b 
    on a.from_number=b.to_number and a.to_number=b.from_number) 

count(*) 替换为count(where) 消息 table 的实体 class 在这里。

    @Entity
    @Table(name = "message")
    public class Message implements Comparable<Message> {

        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "id")
        private Long id;

        @Column(name = "to_number")
        private String toNumber;

        @Column(name = "from_number")
        private String fromNumber;

        @Column(name = "message")
        private String message;

        @Enumerated(EnumType.STRING)
        @Column(name = "direction")
        private MessageDirection direction;

        @Enumerated(EnumType.STRING)
        @Column(name = "status")
        private MessageStatus status;

        @Enumerated(EnumType.STRING)
        @Column(name = "type")
        private KeywordType type;

        @Column(name = "keyword_matched")
        private String keywordMatched;

        @Column(name = "generated_time")
        private Timestamp generatedTime;

        @Column(name = "scheduled_time")
        private Timestamp scheduledTime;

        @Column(name = "details")
        private String details;

        @Enumerated(EnumType.STRING)
        @Column(name = "read_status")
        private MessageReadStatus readStatus;

        @Column(name = "delivery_code")
        private String deliveryCode;

        @Column(name = "delivery_description")
        private String deliveryDescription;

        @Column(name = "data", columnDefinition = "json")
        private String messageData;

        @ManyToOne
        @JoinColumn(name = "schedule_id")
        private Schedule schedule;

        public Message() {
        }

        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public String getToNumber() {
            return toNumber;
        }

        public void setToNumber(String toNumber) {
            this.toNumber = toNumber;
        }

        public String getFromNumber() {
            return fromNumber;
        }

        public void setFromNumber(String fromNumber) {
            this.fromNumber = fromNumber;
        }

        public String getMessage() {
            return message;
        }

        public void setMessage(String message) {
            this.message = message;
        }

        public MessageDirection getDirection() {
            return direction;
        }

        public void setDirection(MessageDirection direction) {
            this.direction = direction;
        }

        public MessageStatus getStatus() {
            return status;
        }

        public void setStatus(MessageStatus status) {
            this.status = status;
        }

        public KeywordType getType() {
            return type;
        }

        public void setType(KeywordType type) {
            this.type = type;
        }

        public Timestamp getGeneratedTime() {
            return generatedTime;
        }

        public void setGeneratedTime(Timestamp generatedTime) {
            this.generatedTime = generatedTime;
        }

        public Timestamp getScheduledTime() {
            return scheduledTime;
        }

        public void setScheduledTime(Timestamp scheduledTime) {
            this.scheduledTime = scheduledTime;
        }

        public Schedule getSchedule() {
            return schedule;
        }

        public void setSchedule(Schedule schedule) {
            this.schedule = schedule;
        }

        public String getKeywordMatched() {
            return keywordMatched;
        }

        public void setKeywordMatched(String keywordMatched) {
            this.keywordMatched = keywordMatched;
        }

        public String getDetails() {
            return details;
        }

        public void setDetails(String details) {
            this.details = details;
        }

        public MessageReadStatus getReadStatus() {
            return readStatus;
        }

        public void setReadStatus(MessageReadStatus readStatus) {
            this.readStatus = readStatus;
        }

        public String getDeliveryCode() {
            return deliveryCode;
        }

        public void setDeliveryCode(String deliveryCode) {
            this.deliveryCode = deliveryCode;
        }

        public String getMessageData() {
            return messageData;
        }

        public void setMessageData(String messageData) {
            this.messageData = messageData;
        }

        public String getDeliveryDescription() {
            return deliveryDescription;
        }

        public void setDeliveryDescription(String deliveryDescription) {
            this.deliveryDescription = deliveryDescription;
        }
    }

为什么要更换它。我怎样才能以正确的方式编写查询?

解决方法是使用countQuery注解参数:

public interface Repository extends JpaRepository<Entity, Long> {

String QUERY = "FROM entity " +
        " WHERE name ILIKE :name ";

@Query(
        value = "SELECT * " + QUERY,
        countQuery = "SELECT count(*) " + QUERY,
        nativeQuery = true
)
Page<KDeploymentView> findBy(
        @Param("name") String name,
        Pageable p
);