Skip to content

[Bug]在sqlite情况下,使用paginate会报错Long不能转为Int #64

Description

@lijialong1313

版本:Maven中央库下的7.0.15最新版。

出错代码如下:

    public Response index(Request request) {
        QueryBuilder<Admin, Long> list = Admin.self().newQuery();
        if (request.has("key") && request.has("value")) {
            list.where(request.get("key", ""), request.get("value", ""));
        }
        Paginate<Admin> result = list.paginate(request.get("page", 1), 15);
        return ResponseBuilder.view("mdui.admin.admin.list", Map.of("list", result));
    }

Java报错如下:

Caused by: java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.Long (java.lang.Integer and java.lang.Long are in module java.base of loader 'bootstrap')
	at gaarason.database.contract.builder.Aggregates.count(Aggregates.java:36) ~[database-api-7.0.15.jar:na]
	at gaarason.database.contract.builder.Aggregates.count(Aggregates.java:27) ~[database-api-7.0.15.jar:na]
	at gaarason.database.query.ExecuteLevel3Builder.paginate(ExecuteLevel3Builder.java:139) ~[database-query-7.0.15.jar:na]
	at gaarason.database.query.AbstractBuilder.paginate(AbstractBuilder.java:31) ~[database-query-7.0.15.jar:na]
	at gaarason.database.contract.builder.Pager.paginate(Pager.java:39) ~[database-api-7.0.15.jar:na]
	at com.weacsoft.system.app.http.controllers.AdminController.index(AdminController.java:22) ~[classes/:na]
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
	at com.weacsoft.jaravel.vendor.http.controller.ControllerActionResolver.lambda$createRunner$2(ControllerActionResolver.java:134) ~[http-0.1.2.jar:0.1.2]
	... 56 common frames omitted

我用AI分析,AI说法如下:

AdminController.index()
  → list.paginate(page, 15)                          // 你的代码
  → ExecuteLevel3Builder.paginate()                  // hasTotal=true → clone().count()
  → Aggregates.count() → count("*")                  // 声明返回 Long
  → AbstractBuilder.aggregate()                       // @github 实际实现
      Map resMap = ...selectFunction("COUNT",...).firstOrFail().toMap();
      return ObjectUtils.typeCast(resMap.get(alias)); // 这里转成 R=Long
  → ObjectUtils.typeCast()
      return (N) original;                            // (Long) 强转 → ClassCastException

count() 接口声明返回 Long(Aggregates.count(String) 的签名是 default Long count(...)),但底层 JDBC 驱动对 COUNT() 的返回值类型取决于数据库方言/驱动:

MySQL Connector/J 8.x 的 COUNT() 通常返回 Long(BigInteger);
但某些驱动/配置(尤其 SQLite JDBC,以及部分旧版/嵌入式驱动)会把 COUNT() 作为 Integer 返回。

可选的修复方向
框架侧(database-all):AbstractBuilder.aggregate 对 COUNT 结果应做 Number → Long(.longValue())兼容转换,而非裸强转。

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions