【问题标题】:Limiting results in a custom FileMaker dialect for Hibernate限制 Hibernate 的自定义 FileMaker 方言中的结果
【发布时间】:2018-09-14 13:54:21
【问题描述】:

我正在尝试使用 Spring JPA 2.0.9 和 Hibernate 5.3.5 访问 FileMaker 16 数据库,使用 the official JDBC driverthis dialect 用于 Hibernate。

我已对方言进行了修改,以使其支持限制 FileMaker 结果集,添加如下限制处理程序:

public class FileMakerDialect extends Dialect {

...

    private static final LimitHandler LIMIT_HANDLER = new AbstractLimitHandler() {
        public String processSql(String sql, RowSelection selection) {
            String soff = " offset ? rows";
            String slim = " fetch first ? rows only";
            StringBuilder sb = (new StringBuilder(sql.length() + soff.length() + slim.length())).append(sql);

            if (LimitHelper.hasFirstRow(selection)) {
                sb.append(soff);
            }

            if (LimitHelper.hasMaxRows(selection)) {
                sb.append(slim);
            }

            return sb.toString();
        }

        public boolean supportsLimit() {
            return true;
        }
    };

    public LimitHandler getLimitHandler() {
        return LIMIT_HANDLER;
    }

...
}

限制处理程序只是将offset ? rows fetch first ? rows only 添加到选择查询的末尾。

现在我有一个测试在尝试从 Spring JPA 存储库获取分页结果时失败:

com.filemaker.jdbc.FMSQLException: [FileMaker][FileMaker JDBC] FQL0001/(1:338):查询的语法有错误。在 com.filemaker.jdbc.FM_API.prepare(未知来源)在 com.filemaker.jdbc.FM_API.prepareRS(未知来源)在 com.filemaker.jdbc.FM_API.prepareRS(未知来源)在 com.filemaker.jdbc1.CommonJ1Statement.(Unknown Source) at com.filemaker.jdbc2.CommonJ2Statement.(未知来源)在 com.filemaker.jdbc3.CommonJ3Statement.(Unknown Source) at com.filemaker.jdbc3.J3PreparedStatement.(Unknown Source) at com.filemaker.jdbc3.J3Connection.prepareStatement(未知来源)在 com.filemaker.jdbc2.CommonJ2Connection.prepareStatement(未知 来源)在 com.zaxxer.hikari.pool.ProxyConnection.prepareStatement(ProxyConnection.java:318) 在 com.zaxxer.hikari.pool.HikariProxyConnection.prepareStatement(HikariProxyConnection.java) 在 org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:146) 在 org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:172) ... 87 更多

但是,如果我从com.zaxxer.hikari.pool.ProxyConnection.prepareStatement(ProxyConnection.java:318) 获取看起来像select * from "MarketingCategories" marketingc0_ offset ? rows fetch first ? rows only 的 SQL,将问号替换为数字并使用相同的驱动程序手动对 FileMaker 数据库执行它,它会成功返回分页结果集。

我该如何处理这个异常?我希望知道如何进一步调试它。没有 fm jdbc 驱动程序的来源,反编译的类也没有行号信息,所以我无法在调试器中检查它。

【问题讨论】:

  • 看起来像 FileMaker JDBC 解析 prepareStatement 中的命令文本时的错误。如果您可以使用 vanilla JDBC 创建minimal reproducible example,请将其发送给 FileMaker 支持,看看他们是怎么说的。

标签: java spring hibernate jdbc filemaker


【解决方案1】:

在报告问题 here 时,我做了一个解决方法:

public class FileMakerDialect extends Dialect {

...

    private static final LimitHandler LIMIT_HANDLER = new AbstractLimitHandler() {
        public String processSql(String sql, RowSelection selection) {
            String soff = String.format(" offset %d rows /*?*/", selection.getFirstRow());
            String slim = String.format(" fetch first %d rows only /*?*/", selection.getMaxRows());
            StringBuilder sb = (new StringBuilder(sql.length() + soff.length() + slim.length())).append(sql);

            if (LimitHelper.hasFirstRow(selection)) {
                sb.append(soff);
            }

            if (LimitHelper.hasMaxRows(selection)) {
                sb.append(slim);
            }

            return sb.toString();
        }

        public boolean supportsLimit() {
            return true;
        }
    };

...
}

它在 cmets 中放置参数绑定的占位符,在限制处理程序中插入分页参数。

【讨论】:

    【解决方案2】:

    在此处查看我关于 johnkeates FileMaker 方言的补丁:https://github.com/fsans/FileMaker-Hibernate-dialect,并进行了一些其他改进。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多