【问题标题】:count( *) query is getting formed instead select (*) query while using Spring Data Jpa and Spring Data Rest在使用 Spring Data Jpa 和 Spring Data Rest 时,正在形成 count(*) 查询而不是 select(*) 查询
【发布时间】:2016-02-27 08:00:28
【问题描述】:

我的 Spring Data Jpa 和基于 Spring Data REST 的应用程序的资源、服务和存储库中有以下代码:

在 Resource.java 中,

// Get User Assigned Customers  by User Id
@RequestMapping(value = "/userAssignedClientss/byUserId",
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
@Timed
    public ResponseEntity<List<UserAssignedClients>> findByUserId(@RequestParam(value="userId") Long userId,
            @RequestParam(value = "page" , required = false) Integer offset,
            @RequestParam(value = "per_page", required = false) Integer limit ) throws URISyntaxException {
        log.debug(" REST request to get User Assigned Clients By User Id " + userId);

        Page<UserAssignedClients> page = userAssignedClientsService.findByUserId(userId, offset, limit);
        HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/userAssignedClientss/byUserId", offset, limit);
        return new ResponseEntity<List<UserAssignedClients>>(page.getContent(), headers, HttpStatus.OK);        
    }

在我的 Service.java 中:

public Page<UserAssignedClients> findByUserId(Long userId, Integer offset, Integer limit) {
    Pageable pageable = new PageRequest(offset, limit, Sort.Direction.ASC, "userId");
    Page<UserAssignedClients> userAssignedClientsList = userAssgClientsRepository.findByUserId(userId, pageable);
    log.debug(" - Returned userAssignedCustomersList Size " + userAssignedClientsList.getSize());

    return userAssgClientsRepository.findByUserId(userId, pageable);
}   

在 Repository.java 中:

Page<UserAssignedClients> findByUserId(Long userId, Pageable pageable); 

我预计查询会形成类似于select * from user_assigned_clients where user_id = ?

但令人惊讶的是,count(*) 查询正在形成,我是空数组作为响应。以下是我在eclipse中的java调试日志。

[DEBUG] com.sample.aop.logging.LoggingAspect - Enter: com.sample.web.rest.UserAssignedClientsResource.findByUserId() with argument[s] = [123456, 1, 10]
[DEBUG] com.sample.web.rest.UserAssignedClientsResource -  : REST request to get User Assigned Clients By User Id 123456
[DEBUG] com.sample.aop.logging.LoggingAspect - Enter: com.sample.service.UserAssignedClientsService.findByUserId() with argument[s] = [123456, 1, 10]
Hibernate: select count(userassign0_.id) as col_0_0_ from user_assigned_clients userassign0_ where userassign0_.user_id=?
[DEBUG] com.sample.service.UserAssignedClientsService -  - Returned userAssignedCustomersList Size 10
Hibernate: select count(userassign0_.id) as col_0_0_ from user_assigned_clients userassign0_ where userassign0_.user_id=?
[DEBUG] com.sample.aop.logging.LoggingAspect - Exit: com.sample.service.UserAssignedClientsService.findByUserId() with result = Page 1 of 1 containing UNKNOWN instances
[DEBUG] com.sample.aop.logging.LoggingAspect - Exit: com.sample.web.rest.UserAssignedClientsResource.findByUserId() with result = <200 OK,[],{X-Total-Count=[1], Link=[</userAssignedClientss/byUserId?page=1&per_page=10>; rel="last",</userAssignedClientss/byUserId?page=1&per_page=10>; rel="first"]}>

以下是我的 UserAssignedClients.java 文件:

/**
 * A UserAssignedClients.
 */
@Entity
@Table(name = "user_assigned_clients")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class UserAssignedClients implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;


    @Column(name = "user_id")
    private Long userId;

    @Column(name = "user_code")
    private String userCode;

    @Column(name = "client_id")
    private Long clientId;

    @Column(name = "client_code")
    private String clientCode;

    @Column(name = "client_name")
    private String clientName;

    public Long getId() {
        return id;
    }

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

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public String getUserCode() {
        return userCode;
    }

    public void setUserCode(String userCode) {
        this.userCode = userCode;
    }

    public Long getClientId() {
        return clientId;
    }

    public void setClientId(Long clientId) {
        this.clientId = clientId;
    }

    public String getClientCode() {
        return clientCode;
    }

    public void setClientCode(String clientCode) {
        this.clientCode = clientCode;
    }

    public String getClientName() {
        return clientName;
    }

    public void setClientName(String clientName) {
        this.clientName = clientName;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        UserAssignedClients userAssignedClients = (UserAssignedClients) o;

        if ( ! Objects.equals(id, userAssignedClients.id)) return false;

        return true;
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(id);
    }

    @Override
    public String toString() {
        return "UserAssignedClients{" +
                "id=" + id +
                ", userId='" + userId + "'" +
                ", userCode='" + userCode + "'" +
                ", clientId='" + clientId + "'" +
                ", clientCode='" + clientCode + "'" +
                ", clientName='" + clientName + "'" +
                '}';
    }
}

【问题讨论】:

  • 鉴于您正在进行分页,因此执行 count(*) 查询是有道理的。计数是否可能为零?在零情况下,我不希望看到执行选择并且空响应是正确的......

标签: hibernate rest spring-data spring-data-jpa spring-data-rest


【解决方案1】:

这是因为您正在请求一个 Pageable 返回值(您返回一个 Page 对象)。 Spring JPA Data 推断您期望多个结果,并且由于您要求 Pagaeble 对象,它所做的第一件事就是尝试获取需要“分页”的记录总数。

如果您阅读documentation 的这一部分,您会看到:

第一种方法允许你传递一个 org.springframework.data.domain.Pageable 实例到查询方法 将分页动态添加到静态定义的查询中。 一个页面 知道可用元素和页面的总数。它确实 所以通过基础设施触发计数查询来计算 总数。

如果您希望返回一些客户端,那么您仍然需要弄清楚为什么 count 返回 0,这意味着它没有通过该 userId 找到您的 Clients。但这是一个不同的问题。

【讨论】:

  • 我需要做哪些改变才能让客户计数 (*)?
  • 正如我所说,这是一个完全不同的问题。我们肯定至少需要您的 JPA 映射对象。
  • 我已经用 UserAssignedClients.java 文件编辑了这个问题。是否足够或我需要提供任何进一步的细节?
  • 嗯,从这里开始调试。我们稍后会看到需要什么。第一件事:你能解释一下你自己的日志消息是如何表明你得到了 10 条记录的吗? 返回的 userAssignedCustomersList 大小 10
  • Gergely,不幸的是我的系统崩溃了,我在复制场景时遇到了问题,如果我回到这个案例,会在这里更新。
猜你喜欢
  • 1970-01-01
  • 2015-08-04
  • 2015-03-25
  • 2022-01-06
  • 2015-01-30
  • 1970-01-01
  • 2018-10-20
  • 1970-01-01
相关资源
最近更新 更多