java - 即使我的 DDL 脚本和 JPA 实体同步,Hibernate 也会抛出验证异常 "wrong column type encountered in column"

标签 java hibernate spring-boot

我在 validate 模式下启动我的 spring 容器

autoddl=validate

我收到这样的验证异常

Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema- 
validation: wrong column type encountered in column [amount] in table [Balance]; 
found [numeric (Types#NUMERIC)], but expecting [int8 (Types#BIGINT)]

我的 DDL 脚本是这样的

CREATE TABLE Balance(stratr VARCHAR(25), histFromDate TIMESTAMP WITHOUT TIME 
ZONE,amount  numeric(11, 0))

我在 JPA 实体中的属性是这样的

 @Column(name="amount", precision=11, scale=0) //have specified precision and scale
 private Long amount  ;

在我使用 import javax.persistence.Column 的地方。由于我已经注释了确切的精度和比例,hibernate 不应该使用我通过列注释提供的这些信息进行验证吗?我可能错过了什么?

我不能做以下事情

  @Column(
   columnDefinition = "NUMERIC(11,0)"
   )
  private Long amount;

因为我不知道这个 JPA 实体的数据存储。

我还尝试通过以下属性生成脚本

<prop key="javax.persistence.schema-generation.scripts.action">drop-and-create</prop>
<prop key="javax.persistence.schema-generation.scripts.create-target">./l/create.sql</prop>
<prop key="javax.persistence.schema-generation.scripts.drop-target">./l/drop.sql</prop> 

这也生成为 int8 而不是 numeric(11,0)。可以做些什么来解决这个问题?

最佳答案

确实很难理解你想要完成的事情,但如果我理解正确的话:

  • 您希望通过不将实体级别的列定义固定为 NUMERIC(11,0) 来保持您的应用程序的可移植性,这将使它成为 Postgres 特定的
  • 同时,您希望您的列对 Postgres 使用 NUMERIC(11,0) 而不是 Hibernate 通常会使用的 INT8在 Postgres 中用于 Long(并希望在验证时在您的架构中找到)

简而言之,您需要一个未反射(reflect)在您的实体映射中的针对每个数据库的自定义。实现这一点的唯一方法是自定义 Hibernate 为您的 Postgres 版本使用的方言。你需要做的是:

  1. 确定为您的 Postgres 数据库选择哪个方言版本(它将是以下之一:PostgresPlusDialectPostgreSQL81DialectPostgreSQL82DialectPostgreSQL91DialectPostgreSQL92DialectPostgreSQL93DialectPostgreSQL94DialectPostgreSQL95DialectPostgreSQL9方言)

  2. 从该类扩展,添加以下定义:

public MyCustomPostgresDialect() {
    super();
    registerColumnType(Types.BIGINT, "NUMERIC(11, 0)");
}

(如果您希望能够使用 @Column(precision = ..., scale = ...)控制精度和比例,请使用 registerColumnType(Types.BIGINT, "NUMERIC($p, $s)") 代替)

  1. hibernate.dialect 属性添加到 persistence.xml,指向自定义方言的完全限定类名

请注意,这当然会影响数据模型中的所有 Long 属性,而不仅仅是相关的特定字段。

关于java - 即使我的 DDL 脚本和 JPA 实体同步,Hibernate 也会抛出验证异常 "wrong column type encountered in column",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56863906/

相关文章:

java - JPA : Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1 上的问题

java - 如何使用Gradle从Spring bootRun中传递扩展的JVM选项?

mysql - Spring Boot JPA 从缓存

java - JVM内部是如何工作的

java - 如何通过查看 visualVM 中的内存分析器结果来查找罪魁祸首类/对象

java - 如何在 JPQL 或 HQL 中进行限制查询?

mysql - Spring DAO rewritebatchedstatements 不适用于具有嵌入 ID 的实体上的 SaveAll()

java - 使用套接字编程将数据从Java发送到C

java - 无法自动配置 session 存储库,请检查您的配置( session 存储类型为 'null' )

java - 具有供应商特定属性的 JPA find() 方法