ERROR: column is of type json but expression is of type character varying in Hibernate
ERROR: column is of type json but expression is of type character varying in Hibernate
我需要使用 spring 数据 jpa 在 postgres 中将实体 class 的两列映射为 json。在阅读了多个 Whosebug posts 和 baeldung post 后,
How to map a map JSON column to Java Object with JPA
https://www.baeldung.com/hibernate-persist-json-object
我做了如下配置。但是,我遇到错误“错误:列“headers”的类型为 json,但表达式的类型为字符变化”
请提供一些解决此问题的建议。
我有一个实体class如下
@Entity
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class Task {
@Id
@GeneratedValue(strategy = IDENTITY)
private Integer id;
private String url;
private String httpMethod;
@Convert(converter = HashMapConverter.class)
@Column(columnDefinition = "json")
private Map<String, String> headers;
@Convert(converter = HashMapConverter.class)
@Column(columnDefinition = "json")
private Map<String, String> urlVariables;
}
我创建了一个测试 class 来测试实体是否持久化。在 运行 这个 junit 上,下面的测试用例失败,错误如下
@SpringBootTest
class TaskRepositoryTest {
private static Task randomTask = randomTask();
@Autowired
private TaskRepository taskRepository;
@BeforeEach
void setUp() {
taskRepository.deleteAll();
taskRepository.save(randomTask);
}
public static Task randomTask() {
return randomTaskBuilder().build();
}
public static TaskBuilder randomTaskBuilder() {
Map<String,String> headers = new HashMap<>();
headers.put(randomAlphanumericString(10),randomAlphanumericString(10));
Map<String,String> urlVariables = new HashMap<>();
urlVariables.put(randomAlphanumericString(10),randomAlphanumericString(10));
return builder()
.id(randomPositiveInteger())
.httpMethod(randomAlphanumericString(10))
.headers(headers)
.urlVariables(urlVariables)
.url(randomAlphanumericString(10)));
}
}
使用 liquibase,我在 postgres 数据库中创建了 table,我可以看到列数据类型为 json。
databaseChangeLog:
- changeSet:
id: 1
author: abc
changes:
- createTable:
tableName: task
columns:
- column:
name: id
type: int
autoIncrement: true
constraints:
primaryKey: true
- column:
name: url
type: varchar(250)
constraints:
nullable: false
unique: true
- column:
name: http_method
type: varchar(50)
constraints:
nullable: false
- column:
name: headers
type: json
- column:
name: url_variables
type: json
rollback:
- dropTable:
tableName: task
以上配置无效。
因此,我按照下面link来解决用例
https://vladmihalcea.com/how-to-map-json-objects-using-generic-hibernate-types/
"Provider com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule not found" after Spring Boot Upgrade
在 pom.xml
中添加了额外的依赖项
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jaxb-annotations</artifactId>
</dependency>
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-52</artifactId>
<version>2.9.11</version>
</dependency>
删除了 HashMapConverter 配置并对实体进行了以下更改 class
@Entity
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@ToString(callSuper = true)
@TypeDefs({
@TypeDef(name = "json", typeClass = JsonStringType.class),
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
})
public class Task {
@Id
@GeneratedValue(strategy = IDENTITY)
private Integer id;
private String url;
private String httpMethod;
@Type(type = "jsonb")
@Column(columnDefinition = "json")
private Map<String, String> headers;
@Type(type = "jsonb")
@Column(columnDefinition = "json")
private Map<String, String> urlVariables;
}
经过这些更改后,TaskRepositoryTest 通过了。
当我将我的项目从 MySQL 8.0.21 迁移到 Postgres 13 时,我 运行 遇到了这个问题。我的项目使用 Spring 引导和 Hibernate 类型依赖版本 2.7.1 .就我而言,解决方案很简单。
我需要做的就是改变它,它奏效了。
对于因为使用 JdbcTemplate
并收到此错误而登陆此处的任何人,解决方案非常简单:在您的 SQL 语句中,使用 JSON 参数转换 ::jsonb
.
例如String INSERT_SQL = "INSERT INTO xxx (id, json_column) VALUES(?, ?)";
变成 String INSERT_SQL = "INSERT INTO xxx (id, json_column) VALUES(?, ?::jsonb)";
我需要使用 spring 数据 jpa 在 postgres 中将实体 class 的两列映射为 json。在阅读了多个 Whosebug posts 和 baeldung post 后,
How to map a map JSON column to Java Object with JPA
https://www.baeldung.com/hibernate-persist-json-object
我做了如下配置。但是,我遇到错误“错误:列“headers”的类型为 json,但表达式的类型为字符变化”
请提供一些解决此问题的建议。
我有一个实体class如下
@Entity
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class Task {
@Id
@GeneratedValue(strategy = IDENTITY)
private Integer id;
private String url;
private String httpMethod;
@Convert(converter = HashMapConverter.class)
@Column(columnDefinition = "json")
private Map<String, String> headers;
@Convert(converter = HashMapConverter.class)
@Column(columnDefinition = "json")
private Map<String, String> urlVariables;
}
我创建了一个测试 class 来测试实体是否持久化。在 运行 这个 junit 上,下面的测试用例失败,错误如下
@SpringBootTest
class TaskRepositoryTest {
private static Task randomTask = randomTask();
@Autowired
private TaskRepository taskRepository;
@BeforeEach
void setUp() {
taskRepository.deleteAll();
taskRepository.save(randomTask);
}
public static Task randomTask() {
return randomTaskBuilder().build();
}
public static TaskBuilder randomTaskBuilder() {
Map<String,String> headers = new HashMap<>();
headers.put(randomAlphanumericString(10),randomAlphanumericString(10));
Map<String,String> urlVariables = new HashMap<>();
urlVariables.put(randomAlphanumericString(10),randomAlphanumericString(10));
return builder()
.id(randomPositiveInteger())
.httpMethod(randomAlphanumericString(10))
.headers(headers)
.urlVariables(urlVariables)
.url(randomAlphanumericString(10)));
}
}
使用 liquibase,我在 postgres 数据库中创建了 table,我可以看到列数据类型为 json。
databaseChangeLog:
- changeSet:
id: 1
author: abc
changes:
- createTable:
tableName: task
columns:
- column:
name: id
type: int
autoIncrement: true
constraints:
primaryKey: true
- column:
name: url
type: varchar(250)
constraints:
nullable: false
unique: true
- column:
name: http_method
type: varchar(50)
constraints:
nullable: false
- column:
name: headers
type: json
- column:
name: url_variables
type: json
rollback:
- dropTable:
tableName: task
以上配置无效。
因此,我按照下面link来解决用例
https://vladmihalcea.com/how-to-map-json-objects-using-generic-hibernate-types/
"Provider com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule not found" after Spring Boot Upgrade
在 pom.xml
中添加了额外的依赖项 <dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jaxb-annotations</artifactId>
</dependency>
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-52</artifactId>
<version>2.9.11</version>
</dependency>
删除了 HashMapConverter 配置并对实体进行了以下更改 class
@Entity
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@ToString(callSuper = true)
@TypeDefs({
@TypeDef(name = "json", typeClass = JsonStringType.class),
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
})
public class Task {
@Id
@GeneratedValue(strategy = IDENTITY)
private Integer id;
private String url;
private String httpMethod;
@Type(type = "jsonb")
@Column(columnDefinition = "json")
private Map<String, String> headers;
@Type(type = "jsonb")
@Column(columnDefinition = "json")
private Map<String, String> urlVariables;
}
经过这些更改后,TaskRepositoryTest 通过了。
当我将我的项目从 MySQL 8.0.21 迁移到 Postgres 13 时,我 运行 遇到了这个问题。我的项目使用 Spring 引导和 Hibernate 类型依赖版本 2.7.1 .就我而言,解决方案很简单。
我需要做的就是改变它,它奏效了。
对于因为使用 JdbcTemplate
并收到此错误而登陆此处的任何人,解决方案非常简单:在您的 SQL 语句中,使用 JSON 参数转换 ::jsonb
.
例如String INSERT_SQL = "INSERT INTO xxx (id, json_column) VALUES(?, ?)";
变成 String INSERT_SQL = "INSERT INTO xxx (id, json_column) VALUES(?, ?::jsonb)";