java - "SQLServerException: String or binary data would be truncated"问题 - 配置 H2 DB 进行诊断,但列大小更改未生效?

标签 java sql-server spring-boot h2 truncation

什么?

在调查 Java Spring Boot 应用程序中的 SQLServerException:字符串或二进制数据将被截断 问题时,我将 H2 配置为替代方案,以便在重新创建场景时提供更好的诊断错误消息和更大的灵 active 。

TLDR? 跳至问题是...

您是如何配置 Spring Boot 应用程序的?

我将 Spring Boot 应用程序配置为使用 H2 数据库而不是 SQL Server,如下所示:

  1. 从 SQL Server 导出架构并创建脚本 db/sql/test.sql 来在 H2 中创建架构和对象 - 为了简洁起见,我已将其缩小为单个字段。

    CREATE SCHEMA IF NOT EXISTS "MYSCHEMA";
    
    CREATE TABLE "MYSCHEMA"."MyTable"
    (
        MyField nvarchar(1500)
    )
    
  2. 为 H2 配置 Maven 依赖项:

    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <version>1.4.197</version>
        <scope>test</scope>
    </dependency>
    
  3. 在 application.yml 中配置数据源以使用 H2:

    spring:
      datasource:
        database: HSQL
        driverClassName: org.h2.Driver
        url: jdbc:h2:mem:MyDBName
        username: sa
        password:
    
  4. 创建了一个测试配置类来定义可注入(inject)数据源 bean,以运行架构创建 test.sql 脚本:

    @Configuration
    public class TestConfiguration {
        @Bean
        public DataSource dataSource() {
            EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
            EmbeddedDatabase db = builder
                .setType(EmbeddedDatabaseType.H2)
                .addScript("db/sql/test.sql")
                .setName("MyDBName")
                .build();
            return db;
        }
    }
    

使用此配置运行应用程序时发生了什么?

配置完成后,我运行了一个测试场景,H2 立即在错误消息中给了我被截断的字段的名称(感谢 H2!)以及将被截断的数据(及其长度)。

增加字段大小是否可以防止错误发生?

出错的列大小为 1500。将脚本和 Hibernate 实体类中的字段大小调整为 2000 后,我的测试用例不再出现数据截断错误。

将列恢复到原始大小后是否仍然出现截断错误?

当我更改 H2 架构创建脚本以将列大小调整为其原始大小 (1500) 时,尽管数据大小 > 1500,但并未发生截断错误。

问题是......?

为什么我在 test.sql 中更改列大小没有任何效果?

最佳答案

发生了什么事?

这些表是由 hibernate 根据实体类本身的定义自动创建的,创建脚本的内容部分被忽略。

实体列长度是什么样的?

@Entity
@Table(name = "myTable", schema="mySchema")
public class myEntity {
    @Column(length=2000) private String myField;
}

需要脚本的哪些部分?

所需的 db/sql/test.sql 脚本的唯一部分是创建架构。

CREATE SCHEMA IF NOT EXISTS "MYSCHEMA";

表格和列怎么样?

所有表、列和列大小都是从 @Entity 类自动生成的。

还有什么需要注意的吗?

是的,了解实体中的所有 String 类型默认为 varchar(255) 的实现也很有用,因此对于任何比此长的字段,您需要指定 @Column(size=...) 注释。

TL;DR?

创建的数据库中的列长度来 self 的 @Column 注释,而不是来自 .sql 脚本的 CREATE TABLE 语句!

附录

现在配置了 H2,我就可以在重放测试用例时轻松地在使用 SQL Server 或使用 H2 之间切换来诊断问题。

谢谢 H2!

H2 的错误消息准确地告诉我哪些数据将被截断、哪一列受到影响,以及实际数据的长度是多少。确定了列和数据后,我就能够深入研究代码以找出它的来源。

关于java - "SQLServerException: String or binary data would be truncated"问题 - 配置 H2 DB 进行诊断,但列大小更改未生效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50710866/

相关文章:

Java线程内存泄漏

java - 将 JSON 解析为对象

sql - 内部联接与交叉应用 - 无法绑定(bind)多部分标识符

c# - 从逗号连接列表创建 SQL 表

java - 无法提取响应 : no suitable HttpMessageConverter found for response type class and content type [text/html]

JavaScript + Spring 启动

java - 将文件从应用程序复制到系统目录?

java - 如何在 'Default Java for browsers'中启用MSIE8?

java - Spring Boot 中使用相同存储库和实体的多个数据源

SQL-如何将两个日期拆分为年度格式