Spring Boot整合PostgreSQL时List类型字段JDBC类型异常问题
Spring Boot整合PostgreSQL时List字段导致启动失败的解决方法
问题场景
在Spring Boot项目中整合PostgreSQL数据库,给Calendar实体类添加List<String>类型的tags字段后,应用启动失败;移除该字段则能正常运行。报错核心信息为:
Expecting BasicPluralJavaType for array class `[Ljava.lang.String;`, but got `com.vladmihalcea.hibernate.type.array.internal.StringArrayTypeDescriptor@1f521c69`
实体类代码
package com.abc.calendar.calendarapi.model; import lombok.*; import java.util.Date; import java.util.List; import java.util.Map; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.Table; @Getter @Setter @NoArgsConstructor @AllArgsConstructor @Entity @Table(name = "calendars") public class Calendar { @Id private String event_id; private String company_id; private String title; private String description; private Date start_time; private Date end_time; private String location; private String color; private String status; private List<String> tags; // private List<Participant> participants; // private Organizer organizer; // private List<Participant> participants; // private List<Attachment> attachments; // private Recurring recurring; // private List<Filter> default_filters; // private Map<String, List<String>> user_filters; }
控制台报错日志
[Tomcat] 2024-05-23T17:53:23.720-04:00 INFO 19864 --- [calendarapi] [ main] .s.b.a.l.ConditionEvaluationReportLogger : Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled. 2024-05-23T17:53:23.752-04:00 ERROR 19864 --- [calendarapi] [ main] o.s.boot.SpringApplication : Application run failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is java.lang.IllegalArgumentException: Expecting BasicPluralJavaType for array class `[Ljava.lang.String;`, but got `com.vladmihalcea.hibernate.type.array.internal.StringArrayTypeDescriptor@1f521c69` at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1786) ~[spring-beans-6.1.6.jar:6.1.6] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600) ~[spring-beans-6.1.6.jar:6.1.6] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) ~[spring-beans-6.1.6.jar:6.1.6] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.1.6.jar:6.1.6] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.6.jar:6.1.6] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.1.6.jar:6.1.6] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.1.6.jar:6.1.6] at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1234) ~[spring-context-6.1.6.jar:6.1.6] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:952) ~[spring-context-6.1.6.jar:6.1.6] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:624) ~[spring-context-6.1.6.jar:6.1.6] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.2.5.jar:3.2.5] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-3.2.5.jar:3.2.5] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) ~[spring-boot-3.2.5.jar:3.2.5] at org.springframework.boot.SpringApplication.run(SpringApplication.java:334) ~[spring-boot-3.2.5.jar:3.2.5] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1354) ~[spring-boot-3.2.5.jar:3.2.5] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) ~[spring-boot-3.2.5.jar:3.2.5] at com.abc.calendar.calendarapi.CalendarapiApplication.main(CalendarapiApplication.java:10) ~[classes/:na] Caused by: jakarta.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is java.lang.IllegalArgumentException: Expecting BasicPluralJavaType for array class `[Ljava.lang.String;`, but got `com.vladmihalcea.hibernate.type.array.internal.StringArrayTypeDescriptor@1f521c69` at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:421) ~[spring-orm-6.1.6.jar:6.1.6] at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[spring-orm-6.1.6.jar:6.1.6] at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:366) ~[spring-orm-6.1.6.jar:6.1.6] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1833) ~[spring-beans-6.1.6.jar:6.1.6] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1782) ~[spring-beans-6.1.6.jar:6.1.6] ... 16 common frames omitted Caused by: java.lang.IllegalArgumentException: Expecting BasicPluralJavaType for array class `[Ljava.lang.String;`, but got `com.vladmihalcea.hibernate.type.array.internal.StringArrayTypeDescriptor@1f521c69` at org.hibernate.loader.ast.internal.MultiKeyLoadHelper.resolveArrayJdbcMapping(MultiKeyLoadHelper.java:46) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final] at org.hibernate.loader.ast.internal.MultiIdEntityLoaderArrayParam.<init>(MultiIdEntityLoaderArrayParam.java:58) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final] at org.hibernate.persister.entity.AbstractEntityPersister.buildMultiIdLoader(AbstractEntityPersister.java:892) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final] at org.hibernate.persister.entity.AbstractEntityPersister.prepareLoaders(AbstractEntityPersister.java:3420) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final] at org.hibernate.metamodel.model.domain.internal.MappingMetamodelImpl.finishInitialization(MappingMetamodelImpl.java:206) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final] at org.hibernate.internal.SessionFactoryImpl.initializeMappingModel(SessionFactoryImpl.java:364) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final] at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:293) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final] at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:450) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final] at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1507) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final] at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:75) ~[spring-orm-6.1.6.jar:6.1.6] at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:390) ~[spring-orm-6.1.6.jar:6.1.6] at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-6.1.6.jar:6.1.6] ... 20 common frames omitted
解决方案
原因分析
Hibernate默认无法直接将List<String>映射到PostgreSQL的数组类型,报错是因为引入的vladmihalcea数组类型处理器与Hibernate原生类型解析逻辑冲突,或是未正确配置类型映射规则。
方法一:使用Hibernate原生数组类型映射(适配PostgreSQL数组字段)
- 确保数据库
calendars表的tags字段类型为text[](PostgreSQL字符串数组类型)。 - 修改实体类
tags字段,添加正确的类型注解:
import jakarta.persistence.Column; import org.hibernate.annotations.JdbcTypeCode; import org.hibernate.type.SqlTypes; // ...其他注解 @Column(columnDefinition = "text[]") @JdbcTypeCode(SqlTypes.ARRAY) private List<String> tags;
方法二:使用JSON/JSONB类型存储(更灵活)
若不需要数组的特定查询特性,可将List<String>序列化为JSON存储:
- 数据库
tags字段类型设为jsonb。 - 实体类字段添加注解:
import org.hibernate.annotations.JdbcTypeCode; import org.hibernate.type.SqlTypes; // ...其他注解 @Column(columnDefinition = "jsonb") @JdbcTypeCode(SqlTypes.JSON) private List<String> tags;
方法三:移除vladmihalcea数组类型依赖(若误引入)
如果项目中不需要hibernate-types库,直接移除相关依赖,避免与Hibernate原生类型处理逻辑冲突。
内容的提问来源于stack exchange,提问作者mustafa imran
相关产品推荐
相关产品推荐

