【问题标题】:Spring Boot with JPA - wrong column type encountered in columnSpring Boot with JPA - 在列中遇到错误的列类型
【发布时间】:2020-02-17 18:35:33
【问题描述】:

我正在使用 Spring Boot Starter Data Jpa (2.1.9.RELEASE),我正在尝试映射此表:

CREATE TABLE `foo` (
  `id` int(11) NOT NULL,
  `woo` tinyint(4) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

Entity 映射如下:

@Entity
@Table(name = "foo")
public class Foo {

    @Id
    @Column(name = "id")
    private Integer id;

    @Column(name = "woo")
    private Integer woo;

    public Integer getId() {
        return id;
    }

    public Integer getWoo() {
        return woo;
    }

}

当我启动应用程序时,我收到以下错误:

Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: wrong column type encountered in column [woo] in table [foo]; found [tinyint (Types#TINYINT)], but expecting [integer (Types#INTEGER)]

我的属性是:

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql:///test
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.ddl-auto=validate

我尝试使用 vanilla Jpa 和 Hibernate(不受 Spring 管理)进行相同的映射,并且效果很好。

谁能指出我正确的方向?

Here's a link to the maven project,以防有人想直接尝试。

【问题讨论】:

标签: java spring hibernate spring-boot jpa


【解决方案1】:

您的数据库正在使用 TinyInt,而您的类正在使其期望一个整数。然而,TinyInt 映射到字节,这就是发生混淆的地方。

@Column(name = "woo")
private Byte woo;

映射类型的参考可以在here找到。

【讨论】:

  • 那为什么如果我使用 JPA + Hibernate(与 spring 管理的版本相同)创建一个简单的 java 项目,它可以完美地工作而无需添加额外的注释?
  • 我真的不知道我是否对你诚实。 Spring Data 只是提供了一个抽象层,它试图让做事更容易并且使用更少的样板代码,但它本身并不是 JPA 提供者(因此它带有 hibernate)。 Hibernate 尝试映射来自数据库的数据类型和来自 Java 的数据类型,并将它们与它自己的休眠类型匹配,如果它们不导致相同的休眠类型,则会导致不匹配。然而,我能找到的一切都表明 Hibernate 会将 TinyInt 映射到 Byte/byte。
  • 我的上述评论可以在这里进一步看到:docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/type/…。使用此处找到的接口比较类型:docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/type/…。如果可能的话,也许您可​​以尝试调试以查看幕后发生的事情,并注意两者之间可能发生的任何差异。除非映射发生变化或在后台发生一些奇怪的数据转换(可能的字符串转换?),否则我想不出可能是什么原因。
  • 如果您确实找出了具体原因,请发表评论,说明如果可以的话 - 我自己也很好奇。
  • 是的,我同意你的观点,我认为也许某些在 Spring 中以某种方式默认的配置在 vanilla Hibernate 中具有另一个默认值。一旦我有更多空闲时间,我会尝试进行更多调查。
【解决方案2】:

JDBC tinyint 等效的 Java 类型是 Byte。 这是休眠文档。 Datatype mapping

如果您使用 eclipse/STS 直接从表中生成实体而没有数据类型冲突,JBoss 工具会很有帮助。

【讨论】:

    【解决方案3】:

    您可能需要使用显式类型声明来覆盖默认的 JDBC 类型 Hibernate:

    @Column(name = "woo", columnDefinition = "TINYINT(4)")
    private Integer woo;
    

    这应该可以解决。

    【讨论】:

    • 我可以在这个属性中使用整数类型,但只有当我从我的 application.properties 文件中删除了这个属性 spring.jpa.properties.hibernate.globally_quoted_identifiers: true
    猜你喜欢
    • 2019-05-10
    • 2021-08-09
    • 1970-01-01
    • 1970-01-01
    • 2018-04-16
    • 2021-08-01
    • 1970-01-01
    • 2018-10-04
    • 1970-01-01
    相关资源
    最近更新 更多