JDBI SqlBatch只插入了一个条目。

huangapple go评论62阅读模式
英文:

JDBI SqlBatch only inserts one entry

问题

我遇到了关于JDBI仅将列表中的第一个项目插入的问题。

    data class UserResourceRow(
      val userId: UserId,
      val roleId: RoleId,
      val resource: Resource,
      val modified: Instant,
      val auditUserId: UserId,
      val deleted: Boolean
    )
    CREATE TABLE `user_resource` (
      `user_id` varchar(36) CHARACTER SET ascii NOT NULL,
      `resource` varchar(36) CHARACTER SET ascii NOT NULL,
      `role_id` int(11) NOT NULL,
      `modified_timestamp` timestamp(3) NOT NULL DEFAULT current_timestamp(3),
      `audit_user_id` varchar(36) CHARACTER SET ascii NOT NULL,
      `deleted` tinyint(1) NOT NULL DEFAULT 0,
      PRIMARY KEY (`user_id`,`resource`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb;
    @Transaction
    @SqlBatch(
        """
        INSERT INTO user_resource
        VALUES (:userId, :resource, :roleId, :modified, :auditUserId, :deleted)
        """
    )
    @Throws(JdbiException::class)
    fun upsert(@BindBean grants: List<UserResourceRow>): IntArray

我用以下方式调用它

    val upsert = grantsDao.upsert(grants)

其中grants是一个包含以下两个元素的列表

    UserResourceRow(userId=22, roleId=123, resource=resource.property.789, modified=2020-05-05T00:48:01.644Z, auditUserId=321, deleted=false)

    UserResourceRow(userId=22, roleId=123, resource=resource.property.456, modified=2020-05-05T00:48:01.644Z, auditUserId=321, deleted=false)

调用成功,upsert返回一个intArray,值为[-2, -2]。

有两个条目的事实告诉我它认为它插入了两行,但我不理解intArray的值为什么是-2和-2,它不应该是一个intArray,其中值为[1, 1]吗?

而且表格仅包含第一个列表条目。

    mysql> select * from user_resource;
    +---------+-----------------------+---------+-------------------------+---------------+---------+
    | user_id | resource              | role_id | modified_timestamp      | audit_user_id | deleted |
    +---------+-----------------------+---------+-------------------------+---------------+---------+
    | 22      | resource.property.789 |      123 | 2020-05-05 00:48:01.644 | 321           |       0 |
    +---------+-----------------------+---------+-------------------------+---------------+---------+
    1行记录 (0.00 )

成功插入一条记录的事实告诉我,@BindBean将列映射到数据类UserResourceRow的属性没有问题,但我不理解为什么只插入了第一个条目。

英文:

I'm having problems with JDBI only inserting the first item in the list

    data class UserResourceRow(
      val userId: UserId,
      val roleId: RoleId,
      val resource: Resource,
      val modified: Instant,
      val auditUserId: UserId,
      val deleted: Boolean
    )
    CREATE TABLE `user_resource` (
      `user_id` varchar(36) CHARACTER SET ascii NOT NULL,
      `resource` varchar(36) CHARACTER SET ascii NOT NULL,
      `role_id` int(11) NOT NULL,
      `modified_timestamp` timestamp(3) NOT NULL DEFAULT current_timestamp(3),
      `audit_user_id` varchar(36) CHARACTER SET ascii NOT NULL,
      `deleted` tinyint(1) NOT NULL DEFAULT 0,
      PRIMARY KEY (`user_id`,`resource`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb;
    @Transaction
    @SqlBatch(
        &quot;&quot;&quot;
        INSERT INTO user_resource
        VALUES (:userId, :resource, :roleId, :modified, :auditUserId, :deleted)
        &quot;&quot;&quot;
    )
    @Throws(JdbiException::class)
    fun upsert(@BindBean grants: List&lt;UserResourceRow&gt;): IntArray

I call this with eg

    val upsert = grantsDao.upsert(grants)

where grants is a list containing these two

    UserResourceRow(userId=22, roleId=123, resource=resource.property.789, modified=2020-05-05T00:48:01.644Z, auditUserId=321, deleted=false)

    UserResourceRow(userId=22, roleId=123, resource=resource.property.456, modified=2020-05-05T00:48:01.644Z, auditUserId=321, deleted=false)

the call succeeds and upsert returns an intArray or [-2, -2]

The fact that there's two entries tells me it thinks it inserted two rows, but I don't understand why the values of the intArray are -2 and -2, shouldn't it be an intArray of [1, 1]?

and the table contains only the first list entry

    mysql&gt; select * from user_resource;
    +---------+-----------------------+---------+-------------------------+---------------+---------+
    | user_id | resource              | role_id | modified_timestamp      | audit_user_id | deleted |
    +---------+-----------------------+---------+-------------------------+---------------+---------+
    | 22      | resource.property.789 |      123 | 2020-05-05 00:48:01.644 | 321           |       0 |
    +---------+-----------------------+---------+-------------------------+---------------+---------+
    1 row in set (0.00 sec)

The fact that it successfully inserted one entry tells me there's no problem with @BindBean mapping the columns to the attributes of the data class UserResourceRow, but I don't understand why only the first entry is inserted?

答案1

得分: 2

我花了很多时间来尝试调试这个问题,但是在 JDBI 或者驱动程序中都没有找到任何问题 - 发送到服务器的套接字上的语句看起来都很正常。(而且它们也确实正常)

事实证明,这可能与测试中使用的底层内存数据库的一些微妙版本差异有关

        &lt;dependency&gt;
            &lt;groupId&gt;ch.vorburger.mariaDB4j&lt;/groupId&gt;
            &lt;artifactId&gt;mariaDB4j&lt;/artifactId&gt;
            &lt;version&gt;2.3.0&lt;/version&gt;
        &lt;/dependency&gt;

以及所使用的 mariadbclient

        &lt;dependency&gt;
            &lt;groupId&gt;org.mariadb.jdbc&lt;/groupId&gt;
            &lt;artifactId&gt;mariadb-java-client&lt;/artifactId&gt;
            &lt;version&gt;2.2.1&lt;/version&gt;
        &lt;/dependency&gt;

因为当我将它们升级到

        &lt;dependency&gt;
            &lt;groupId&gt;ch.vorburger.mariaDB4j&lt;/groupId&gt;
            &lt;artifactId&gt;mariaDB4j&lt;/artifactId&gt;
            &lt;version&gt;2.4.0&lt;/version&gt;
        &lt;/dependency&gt;

        &lt;dependency&gt;
            &lt;groupId&gt;org.mariadb.jdbc&lt;/groupId&gt;
            &lt;artifactId&gt;mariadb-java-client&lt;/artifactId&gt;
            &lt;version&gt;2.6.0&lt;/version&gt;
        &lt;/dependency&gt;

问题就不再复现。

org.mariadb.jdbc.internal.protocol.AbstractQueryProtocol 中有一些与版本和批量语句有关的有趣行,也许不匹配的地方就在其中。

英文:

I spent A LOT of time trying to debug this, and couldn't find anything wrong with neither JDBI or the driver - the statements that went out on the socket to the server looked fine. (and they were)

Turns out this must have had to do with some subtle version discrepancy between the underlying in-memory db used in the test

        &lt;dependency&gt;
            &lt;groupId&gt;ch.vorburger.mariaDB4j&lt;/groupId&gt;
            &lt;artifactId&gt;mariaDB4j&lt;/artifactId&gt;
            &lt;version&gt;2.3.0&lt;/version&gt;
        &lt;/dependency&gt;

and the mariadbclient used

        &lt;dependency&gt;
            &lt;groupId&gt;org.mariadb.jdbc&lt;/groupId&gt;
            &lt;artifactId&gt;mariadb-java-client&lt;/artifactId&gt;
            &lt;version&gt;2.2.1&lt;/version&gt;
        &lt;/dependency&gt;

because when I bump them to

        &lt;dependency&gt;
            &lt;groupId&gt;ch.vorburger.mariaDB4j&lt;/groupId&gt;
            &lt;artifactId&gt;mariaDB4j&lt;/artifactId&gt;
            &lt;version&gt;2.4.0&lt;/version&gt;
        &lt;/dependency&gt;

and

        &lt;dependency&gt;
            &lt;groupId&gt;org.mariadb.jdbc&lt;/groupId&gt;
            &lt;artifactId&gt;mariadb-java-client&lt;/artifactId&gt;
            &lt;version&gt;2.6.0&lt;/version&gt;
        &lt;/dependency&gt;

the issue doesn't reproduce.

There are some interesting lines in org.mariadb.jdbc.internal.protocol.AbstractQueryProtocol to do with versions and bulk/batch statements, maybe the mismatch was in there somewhere.

huangapple
  • 本文由 发表于 2020年5月5日 09:05:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/61604134.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定