【问题标题】:Caused by: org.h2.jdbc.JdbcSQLDataException: Hexadecimal string contains non-hex character引起:org.h2.jdbc.JdbcSQLDataException:十六进制字符串包含非十六进制字符
【发布时间】:2019-12-26 17:46:44
【问题描述】:

我正在尝试使用内存数据库编写测试。 我写了一个 sql 来清理数据并将其存储到数据库。但我有一个例外:

Caused by: org.h2.jdbc.JdbcSQLDataException: Hexadecimal string contains non-hex character: "e7485042-b46b-11e9-986a-b74e614de0b0"; SQL statement:
insert into users (user_id, name, created_on, modified_on) values ('e7485042-b46b-11e9-986a-b74e614de0b0', 'Ann', null, null) -- ('e7485042-b46b-11e9-986a-b74e614de0b0', 'Ann', NULL, NULL) [90004-199]

我的 sql:

insert into users (user_id, name, created_on, modified_on) values ('e7485042-b46b-11e9-986a-b74e614de0b0', 'Ann', null, null);

insert into product(product_id, name, created_on, modified_on) VALUES ('f3a775de-b46b-11e9-95e4-af440b6044e6', 'product1', '2019-08-01 17:51:51.000000', '2019-08-01 17:51:51.000000');

insert into products_users(user_id, product_id) VALUES ('e7485042-b46b-11e9-986a-b74e614de0b0', 'f3a775de-b46b-11e9-95e4-af440b6044e6');

我的 application.properties:

spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=

spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

【问题讨论】:

  • 尝试从 UUID 字符串值中删除连字符。
  • user_id的数据类型是什么?
  • @MarkRotteveel, uuid
  • @GordThompson,然后我得到 MethodArgumentTypeMismatchException:无法将类型“java.lang.String”的值转换为所需类型“java.util.UUID”;嵌套异常是 java.lang.IllegalArgumentException: Invalid UUID string: e7485042b46b11e9986ab74e614de0b0
  • 删除连字符意味着您最终会得到一个不遵守 UUID 格式约定的字符串。从二进制格式重新转换为有效的 UUID 会导致类型不匹配。

标签: java spring jpa jdbc


【解决方案1】:

我通过将spring.jpa.hibernate.ddl-auto=none 添加到我的application.properties 文件中解决了这个问题

【讨论】:

  • 这怎么可能? ddl-auto=none 将阻止在您的 h2 数据库中创建表,因此无法插入任何条目....此外:如果您正在使用 spring boot 并且在您的类路径中有 h2(范围测试),h2 是自动的为您配置,使您的配置变得多余(控制台启用 = true 除外)
  • 这与问题的主题完全无关
【解决方案2】:

此问题的实际原因是您的对象与 hibernate (ddl-auto:create) 生成的用于创建 h2 数据库架构的 create table 语句之间的映射。

如果您使用以下命令启用这些 ddl 语句的输出:

spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.type=TRACE

您很可能会看到您的 UUID 类已映射到数据库中的 binary 列。

Hibernate: 
    create table <your_table> (
        id bigint generated by default as identity,
        ...,
        <your_object> binary(255),
        ...
        primary key (id)
    )

这意味着您的 uuid 字符串映射到二进制列,因此包含非法字符。您需要一个 varchar(&lt;uuid-length&gt;) 列来存储 uuid。有几种解决方案策略,其中之一是定义类型,请参阅此StackOverflow answer。您可以阅读官方MySQL reference site上的binary专栏。

【讨论】:

    【解决方案3】:

    使用 spring.datasource.url=jdbc:h2:mem:testdb;MODE=MYSQL 为我修复了它。

    或者向 UUID 字段添加注释 @Type 应该可以解决问题:

    @Id
    @Type(type="uuid-char")
    private UUID user_id;
    

    【讨论】:

    • 你能解释一下这是做什么的吗?
    • 我的回答,实际上解释了导致这种情况的原因,并且没有提供复制粘贴答案。 ;-)
    猜你喜欢
    • 2023-04-08
    • 2014-10-07
    • 2014-03-26
    • 2010-10-04
    • 2014-03-07
    • 2019-07-27
    • 2018-01-31
    • 2012-06-05
    • 1970-01-01
    相关资源
    最近更新 更多