我正在升级现有的微服务,并使用一些新功能扩展数据库。
我将程序升级为使用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支持Zoned Timestmaps
- 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-jsr 310包含到项目中,那么spring应该自动配置jackson对象Map器来使用该模块。如果可能的话,我希望使用这种行为,而不是通过其他方式自定义对象Map器。
我找到了一些可能的解决方案并尝试了一下。我尝试的方法是
1.添加com.fasterxml.jackson.datatype:jackson-datatype-jsr310
依赖项
1.将@TimeZoneStorage
添加到使用ZonedDateTime
的属性上的@Entity
类
1.将spring.jackson.serialization.write_dates_as_timestamps=true
添加到application.properties
所有解决方案似乎都无法解决该错误。我对解决方案(2)持怀疑态度,因为我怀疑它被Hibernate 6的行为所取代,它会根据数据库和Java类型自动选择正确的转换。解决方案(3)也让我感到怀疑,因为它似乎定义了一个行为,而这个行为现在被期望在hibernate 6中自动化,并且可能会导致问题。
1条答案
按热度按时间atmip9wb1#
在进一步调试之后,我确认spring确实将新模块加载到ObjectMapper中。
这使我发现问题实际上是由另一个对象Map器引起的,该对象Map器是为了进行一些日志记录而创建的。我通过让它从spring上下文自动连接ObjectMapper示例而不是创建本地版本来解决这个问题。或者,您可以让它通过本地示例的构建器加载模块。
我还发现了一个有趣的结论。
jackson-datatype-jsr 310模块现在被认为是遗留的。JavaTime模块包含在Jackson核心中,但未自动注册。这可以在官方文档here中找到。
请注意,从2.6开始,该模块不支持自动注册,因为存在遗留版本JSR 310 Module。旧版本具有相同的功能,但默认配置略有不同:详情请参见JSR 310模块。