Spring Data Rest API使用UUID报错,求兼容解决方案
问题描述
配置了如下实体类:
@Entity @RestResource public class Employee { @Id @GeneratedValue @Type(type = "pg-uuid") private UUID id; @OneToMany(mappedBy = "employee") @RestResource(path = "projects", rel = "projects") private List<EmployeeToProject> projects; } @Entity @RestResource public class Project { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @OneToMany(mappedBy = "project", cascade = CascadeType.ALL, orphanRemoval = true) @RestResource(path = "employees", rel = "employees") private List<EmployeeToProject> employees; } @Entity @RestResource public class EmployeeToProject { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne @RestResource(path = "employee", rel = "employee") private Employee employee; @ManyToOne @RestResource(path = "project", rel = "project") private Project project; }
并为EmployeeToProject配置了仓库:
@RepositoryRestResource @CrossOrigin("*") public interface EmployeeToProjectRepository extends PagingAndSortingRepository<EmployeeToProjectRepository, Long> { }
注:仓库代码存在笔误,应将泛型参数改为
EmployeeToProject而非EmployeeToProjectRepository,正确写法为:@RepositoryRestResource @CrossOrigin("*") public interface EmployeeToProjectRepository extends PagingAndSortingRepository<EmployeeToProject, Long> { }
调用Spring Data Rest的API创建employee_to_project记录时,抛出NumberFormatException,错误信息如下:
"message": "JSON parse error: Failed to convert from type [java.lang.String] to type [java.lang.Long] for value 'e21d6b85-371f-485d-ba5b-b807e2c79093'; nested exception is java.lang.NumberFormatException: For input string: \"e21d6b85-371f-485d-ba5b-b807e2c79093\"; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Failed to convert from type [java.lang.String] to type [java.lang.Long] for value 'e21d6b85-371f-485d-ba5b-b807e2c79093'; nested exception is java.lang.NumberFormatException: For input string: \"e21d6b85-371f-485d-ba5b-b807e2c79093\"
将Employee的ID改为Long类型后API可正常工作,现需在保留UUID作为Employee ID的前提下,让API正常运行。
解决方案
1. 修复仓库泛型笔误
先修正EmployeeToProjectRepository的泛型参数,确保第一个参数为EmployeeToProject,否则仓库无法正确关联实体类。
2. 配置Jackson支持UUID类型转换
Spring Data Rest依赖Jackson处理JSON序列化/反序列化,需确保Jackson能正确识别UUID类型:
方式一:添加依赖
如果使用Maven,在pom.xml中添加:
<dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jdk8</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-uuid</artifactId> </dependency>
如果使用Gradle,在build.gradle中添加:
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jdk8' implementation 'com.fasterxml.jackson.datatype:jackson-datatype-uuid'
方式二:自定义配置类
创建配置类手动注册UUID模块:
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.uuid.UUIDModule; import org.springframework.context.annotation.Configuration; import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer; @Configuration public class RestConfig implements RepositoryRestConfigurer { @Override public void configureJacksonObjectMapper(ObjectMapper objectMapper) { objectMapper.registerModule(new UUIDModule()); } }
3. 优化Employee实体ID注解
在Employee的ID字段上补充@JsonFormat注解,明确UUID的格式:
import com.fasterxml.jackson.annotation.JsonFormat; // ...其他注解 @Id @GeneratedValue @Type(type = "pg-uuid") @JsonFormat(shape = JsonFormat.Shape.STRING) private UUID id;
4. 使用HAL规范的关联链接(推荐)
Spring Data Rest遵循HAL规范,创建关联记录时,推荐传入实体的API链接而非直接传ID值,例如创建EmployeeToProject的请求体:
{ "employee": "http://localhost:8080/employees/e21d6b85-371f-485d-ba5b-b807e2c79093", "project": "http://localhost:8080/projects/1" }
这种方式能彻底避免ID类型转换问题,同时符合RESTful设计规范。
内容的提问来源于stack exchange,提问作者user09
相关产品推荐
相关产品推荐

