java - 使用分页时,在 spring jpa native 查询中,'select count(*) from' 被替换为 'select count(where)'

标签 java spring spring-data-jpa nativequery

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

    @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) 替换 消息表的实体类在这里。

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

关于java - 使用分页时,在 spring jpa native 查询中,'select count(*) from' 被替换为 'select count(where)',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57176630/

相关文章:

hibernate - 如何将构造函数映射与 Spring JPA 存储库结合使用

java - 在多对多单向映射中持久化枚举集

java - 比较 boolean 值时,JUnit Mockito 在assertEquals 中始终返回 false

java - 如何修复 "Exception in thread "main"java.lang.NoClassDefFoundError : org/springframework/core/io/support/SpringFactoriesLoader"in Spring Tool Suite

java - 并非所有 Spring JPA 和数据源属性都在控制台应用程序中工作

java - JPQL 带条件的左外连接

java - 两种不同的 View 取决于使用 Spring MVC 3 的 URL 文件扩展名

java - Rest API 中的 JWT token 传递

java - 无法解析插件 Java Spring