如何通过Jackson将嵌套JSON字段映射到Hibernate实体直接属性
问题描述
从REST API获取到指定JSON数据,当前通过中间类AnnouncementExternalIds实现Jackson JSON映射,但希望将announcementCustomerIDs、announcementOfficeIDs、announcementPositionIDs直接映射到Announcement实体的属性上,以便更便捷地使用Hibernate将对象保存到数据库。
返回的JSON结构
{ "announcementData": [ { "departmentId": 1, "announcementId": 12345, "announcementNumber": "Test Ann", "announcementExternalIDs": { "announcementCustomerIDs": [ { "departmentId": 1, "announcementId": 12345, "customerId": 111 } ], "announcementOfficeIDs": [ { "departmentId": 1, "announcementId": 12345, "officeId": 1 } ], "announcementPositionIDs": [ { "departmentId": 1, "announcementId": 12345, "positionId": 98765 } ] } } ] }
当前映射实现
当前通过中间类承接嵌套的ID列表:
Announcement实体(当前)
@Entity @Table(name = "ANNOUNCEMENT") public class Announcement { @Id @JsonProperty("announcementId") private long announcementId; @JsonProperty("departmentId") private int departmentId; @JsonProperty("announcementNumber") private String announcementNumber; @JsonProperty("announcementExternalIDs") private AnnouncementExternalIds announcementExternalIDs; }
AnnouncementExternalIds中间类
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonPropertyOrder({"announcementCustomerIDs", "announcementOfficeIDs", "announcementVacancyIDs"}) public class AnnouncementExternalIds { @JsonProperty("announcementCustomerIDs") private List<AnnouncementCustomerId> announcementCustomerIds = new ArrayList<>(); @JsonProperty("announcementOfficeIDs") private List<AnnouncementOfficeId> announcementOfficeIds = new ArrayList<>(); @JsonProperty("announcementPositionIDs") private List<AnnouncementPositionID> announcementPositionIDs= new ArrayList<>(); }
AnnouncementCustomerId实体
@Entity @Table(name = "ANNOUNCEMENT_CUSTOMER_ID") public class AnnouncementCustomerId { @JsonProperty("departmentId") private String departmentId; @JsonProperty("announcementId") private String announcementId; @Id @JsonProperty("customerId") private String customerId; }
期望的实体结构
希望直接将嵌套的ID列表映射到Announcement实体属性,无需中间类:
@Entity @Table(name = "ANNOUNCEMENT") public class Announcement { @Id @JsonProperty("announcementId") private long announcementId; @JsonProperty("departmentId") private int departmentId; @JsonProperty("announcementNumber") private String announcementNumber; @JsonProperty("announcementCustomerIDs") private List<AnnouncementCustomerId> announcementCustomerIds = new ArrayList<>(); @JsonProperty("announcementOfficeIDs") private List<AnnouncementOfficeId> announcementOfficeIds = new ArrayList<>(); @JsonProperty("announcementPositionIDs") private List<AnnouncementPositionID> announcementPositionIDs= new ArrayList<>(); }
解决方案
利用Jackson的属性路径映射功能,通过@JsonProperty指定嵌套属性的完整路径,即可跳过中间类直接完成映射。
修改后的Announcement实体类
@Entity @Table(name = "ANNOUNCEMENT") public class Announcement { @Id @JsonProperty("announcementId") private long announcementId; @JsonProperty("departmentId") private int departmentId; @JsonProperty("announcementNumber") private String announcementNumber; // 直接映射嵌套在announcementExternalIDs下的announcementCustomerIDs @JsonProperty("announcementExternalIDs.announcementCustomerIDs") private List<AnnouncementCustomerId> announcementCustomerIds = new ArrayList<>(); // 直接映射嵌套在announcementExternalIDs下的announcementOfficeIDs @JsonProperty("announcementExternalIDs.announcementOfficeIDs") private List<AnnouncementOfficeId> announcementOfficeIds = new ArrayList<>(); // 直接映射嵌套在announcementExternalIDs下的announcementPositionIDs @JsonProperty("announcementExternalIDs.announcementPositionIDs") private List<AnnouncementPositionID> announcementPositionIDs = new ArrayList<>(); // 需添加getter、setter方法,满足Hibernate属性访问要求 }
额外配置说明
- Hibernate关联配置:为了顺利保存到数据库,需要为
Announcement与关联实体配置正确的关联注解,示例如下:
同时在关联实体(如@OneToMany(mappedBy = "announcement", cascade = CascadeType.ALL, orphanRemoval = true) @JsonProperty("announcementExternalIDs.announcementCustomerIDs") private List<AnnouncementCustomerId> announcementCustomerIds = new ArrayList<>();AnnouncementCustomerId)中添加Announcement引用:@ManyToOne @JoinColumn(name = "announcement_id") private Announcement announcement; - 版本兼容性:确保使用Jackson 2.x及以上版本,该版本支持属性路径映射功能。
- 属性名匹配:注解中指定的路径需与JSON中的属性名完全一致,包括大小写。
内容的提问来源于stack exchange,提问作者Tony
相关产品推荐
相关产品推荐

