我正在升级现有的微服务,并用一些新功能扩展数据库。
我将程序升级为使用Spring 3.0.6,它使用hibernate 6.1.7。我使用的数据库是postgresl testcontainers 1.18.1。
当我试图运行我的程序时,它在试图将数据持久化到数据库中时崩溃。它提供的错误如下。。。
java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.ZonedDateTime` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling ...
当我调查这个问题时,我确实证实了
-
Postgresql支持分区时间表
-
Hibernate 6支持
ZonedDateTime
以下是该项目的一些剪辑。
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.6</version>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-csv</artifactId>
</dependency>
<!-- Java 8 Date/time -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
@Entity
@Table(name="billable_Data",schema="mySchema")
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class BillableMetric {
@Id
UUID guid;
@ManyToOne(fetch = FetchType.LAZY)
CustomerInvoice invoice;
@ManyToOne(fetch = FetchType.LAZY)
CustomerRecord billingAccount;
@OneToOne(fetch = FetchType.LAZY)
CatalogueItem skuItem;
@Column(name="dataSourceIdentifier")
BillableMetricDataSource dataSource;
Double quantity;
String unitType;
ZonedDateTime startTimeInclusive;
ZonedDateTime endTimeExclusive;
}
表架构
CREATE TABLE mySchema.billable_Data (
guid uuid NOT NULL DEFAULT mySchema.gen_random_uuid(),
invoice bigserial,
billingAccount uuid, -- Can be null since one possible error is the billing account cannot be found
skuItem bigserial, -- Can be null since one possible error is the sku is not valid.
dataSource numeric NOT NULL, --Should be an enum that is associated to a MetricReading Table
quantity numeric,
unitType varchar(100),
startTimeInclusive timestamp ,
endTimeExclusive timestamp ,
CONSTRAINT guid_is_pk PRIMARY KEY (guid),
CONSTRAINT invoice_is_fk FOREIGN KEY (invoice) REFERENCES mySchema.customer_invoice(id),
CONSTRAINT billable_data_sku_is_fk FOREIGN KEY (skuItem) REFERENCES mySchema.catalog_item(id),
CONSTRAINT billable_data_billing_account_is_fk FOREIGN KEY (billingAccount) REFERENCES mySchema.customer(guid)
);
我读到的是,如果我在项目中包含jackson-datatype-jsr310,那么spring应该自动配置jackson对象映射器以使用该模块。如果可能的话,我希望使用这种行为,而不是通过其他方式自定义对象映射器。
我查找了一些可能的解决方案并进行了尝试。我试过的是
-
添加
com.fasterxml.jackson.datatype:jackson-datatype-jsr310
依赖
-
添加
@TimeZoneStorage
到
@Entity
使用的属性上的类
分区日期时间
-
正在添加
spring.jackson.serialization.write_dates_as_timestamps=true
到
application.properties
似乎没有一个解决方案能解决这个错误。我对解决方案(2)持怀疑态度,因为我怀疑它被Hibernate 6的行为所取代,在Hibernate 6中,它会根据数据库和java类型自动选择正确的转换。解决方案(3)也让我感到怀疑,因为它似乎正在定义一种行为,该行为现在有望通过hibernate 6实现自动化,并可能导致问题。