java - 为什么我的 H2 数据库/Spring 启动应用程序会收到 JdbcSQLException(非十六进制字符)?

标签 java hibernate spring-boot spring-data-jpa h2

所以简短的版本,我猜我有某种字符编码问题,或者数据库正在以 Hibernate/Spring-jpa 出于某种原因不喜欢的格式存储/返回日期。

但如果我能弄清楚哪里出了问题,我会很兴奋!

使用 Hibernate 5 在实体 Prop 中使用 J8 LocalDate 东西。

正在创建数据库并正常插入数据(您将在下面的日志片段中看到我返回了一个日期值)。

日志片段:

2016-10-26 13:25:19.885 ERROR 1028 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.orm.jpa.JpaSystemException: 
Could not read entity state from ResultSet : EntityKey[uk.co.deditech.entity.Person#2]; 
nested exception is org.hibernate.exception.GenericJDBCException: Could not read entity state from ResultSet : 
EntityKey[uk.co.deditech.entity.Person#2]] with root cause org.h2.jdbc.JdbcSQLException: Hexadecimal string contains non-hex character: "2016-03-23" [90004-192]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345) ~[h2-1.4.192.jar:1.4.192]
at org.h2.message.DbException.get(DbException.java:179) ~[h2-1.4.192.jar:1.4.192]
at org.h2.message.DbException.get(DbException.java:155) ~[h2-1.4.192.jar:1.4.192]
at org.h2.util.StringUtils.convertHexToBytes(StringUtils.java:986) ~[h2-1.4.192.jar:1.4.192]
at org.h2.value.Value.convertTo(Value.java:973) ~[h2-1.4.192.jar:1.4.192]
at org.h2.value.Value.getBytes(Value.java:422) ~[h2-1.4.192.jar:1.4.192]
at org.h2.jdbc.JdbcResultSet.getBytes(JdbcResultSet.java:1077) ~[h2-1.4.192.jar:1.4.192]
<snip>

Gradle :

compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-data-jpa")
compile("org.springframework.boot:spring-boot-starter-freemarker")
compile group: 'com.h2database', name: 'h2', version:'1.4.192'

实体:

@Entity
@Table(name = "person")
public @Data class Person {
   ...
   @Column(name = "last_grading_date", nullable = true)
   private LocalDate lastGradingDate;
}

Spring Boot 自动数据库创建脚本片段:

schema.sql
create table PERSON
(
id int not null,
last_grading_date date
)

data.sql
insert into person (id, last_grading_date)
values (1, '2015-02-20');

属性(问题出现在我添加下面的编码属性之前和之后):

spring.datasource.url=jdbc:h2:mem:AZ;DB_CLOSE_DELAY=-1;
spring.datasource.driverClassName=org.h2.Driver
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.datasource.sql-script-encoding=UTF-8

编辑: 经过更多挖掘后,我发现“验证”是 spring.jpa.hibernate.ddl-auto 属性的设置。所以我试过了。

我现在在启动过程中遇到以下错误...

Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: wrong column type encountered in column [last_grading_date] in table [person]; found [date (Types#DATE)], but expecting [binary(255) (Types#VARBINARY)]
at org.hibernate.tool.schema.internal.SchemaValidatorImpl.validateColumnType(SchemaValidatorImpl.java:105) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]

最佳答案

我通过在我的 pom 中添加这个依赖项来让它工作:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-java8</artifactId>
    <version>${hibernate.version}</version>
</dependency>

我不知道为什么它不能开箱即用,但有了这种依赖性,它就解决了这个问题。

我还在属性下添加了这个属性:<hibernate.version>5.0.5.Final</hibernate.version>

我的重现示例代码:

数据.sql:

insert into person (id, last_grading_date)
values (1, '2015-02-20');

application.properties

spring.datasource.url=jdbc:h2:mem:AZ;DB_CLOSE_DELAY=-1;
spring.datasource.driverClassName=org.h2.Driver
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.datasource.sql-script-encoding=UTF-8

个人资料库

public interface PersonRepository extends JpaRepository<Person, Integer>{

}

@Entity
@Table(name = "person")
public class Person {

    @Id
    @Column
    private int id;

    @Column(name = "last_grading_date", nullable = true)
    @Type(type = "java.time.LocalDate")
    private LocalDate lastGradingDate;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public LocalDate getLastGradingDate() {
        return lastGradingDate;
    }

    public void setLastGradingDate(LocalDate lastGradingDate) {
        this.lastGradingDate = lastGradingDate;
    }
}

应用

@SpringBootApplication
public class TestApplication implements CommandLineRunner{

    @Autowired
    PersonRepository repo;

    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }

    @Override
    public void run(String... arg0) throws Exception {
        Person p = repo.findOne(1);
        System.out.println(p.getLastGradingDate());
    }
}

结果:2015-02-20


GitHub 上添加了一个工作示例.该演示基于 Spring-boot 构建, Java 8 , Hibernate 5 , mavenjava.time.LocalDate .

关于java - 为什么我的 H2 数据库/Spring 启动应用程序会收到 JdbcSQLException(非十六进制字符)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40262584/

相关文章:

java - Sqlite 与 hibernate 和 spring-boot

java - 为什么 onResume() 似乎被调用了两次?

java - 当我使用 ddl-auto=create 时,JPA/hibernate 未生成其中一张表

java - Bean创建异常: Error creating bean with name 'userController' : Injection of autowired dependencies failed

mysql - 亚搏体育appGitLab CI : My Test Job doesn't pickup the mysql container

java - 在 Java 之前编译 Groovy 后,Grails 应用程序(配置文件rest-api)陷入困惑

java - Maven Mojo 的编程实例化?

java - 使用内部管道查找 Mongo java 驱动程序

java - 如何在 Firebase 的 Android SDK 中监听单个字段

java - 如何在oracle兼容模式和hibernate中使用hsqldb获取序列的下一个值