【发布时间】:2018-11-17 15:47:00
【问题描述】:
我有一个从 Spring Boot ReST 控制器返回的“人员”对象列表。输出很好,除了一个问题。
这个Personnel 对象有一个PersonnelType 对象作为它的嵌套对象之一。在序列化List中的第一个Personnel对象时,PersonnelType的整个子对象都被序列化了,这就是我想要的。
但是,如果 List 中的第二个或后续 Personnel 对象与第一个 Personnel 对象中已序列化的 PersonnelType 具有相同的 PersonnelType(相同 id),则这些后续 PersonnelType 对象仅使用“id”序列化,而不是整个对象。
例如,这里是序列化的输出:
[
{
"id": 2,
"creatorUserId": null,
"creationTime": null,
"lastModifierUserId": null,
"lastModificationTime": null,
"workforceId": 9994323221,
"workPhoneNumber": "7034563452",
"workEmailAddress": "xxx@epa.gov",
"currentPosition": "Developer",
"isSponsored": false,
"dateOfSponsorship": null,
"sponsorPersonnelId": null,
"isLEO": true,
"isFERO": false,
"requireComputerAndEmailAccess": true,
"isPriorityCase": false,
"building": {
"id": 1,
"creatorUserId": null,
"creationTime": null,
"lastModifierUserId": null,
"lastModificationTime": null,
"isActive": true,
"buildingName": "Robert C Byrd Courthouse and FOB",
"buildingNumber": "406",
"displayGlobal": false,
"facilityName": "Robert C Byrd Courthouse",
"facilityNumber": "107",
"handler": {},
"hibernateLazyInitializer": {}
},
"personnelType": {
"id": 1,
"creatorUserId": null,
"creationTime": null,
"lastModifierUserId": null,
"lastModificationTime": null,
"description": "Federal Employee",
"isActive": true,
"handler": {},
"hibernateLazyInitializer": {}
}
},
{
"id": 2,
"creatorUserId": null,
"creationTime": null,
"lastModifierUserId": null,
"lastModificationTime": null,
"workforceId": 9994323221,
"workPhoneNumber": "7034563452",
"workEmailAddress": "xxx@epa.gov",
"currentPosition": "Developer",
"isSponsored": false,
"dateOfSponsorship": null,
"sponsorPersonnelId": null,
"isLEO": true,
"isFERO": false,
"requireComputerAndEmailAccess": true,
"isPriorityCase": false,
"building": {
"id": 1,
"creatorUserId": null,
"creationTime": null,
"lastModifierUserId": null,
"lastModificationTime": null,
"isActive": true,
"buildingName": "Robert C Byrd Courthouse and FOB",
"buildingNumber": "406",
"displayGlobal": false,
"facilityName": "Robert C Byrd Courthouse",
"facilityNumber": "107",
"handler": {},
"hibernateLazyInitializer": {}
},
"personnelType": 1
}
]
在上面,序列化 List 中的第一个 Personnel 对象具有序列化 PersonnelType 的完整对象,而序列化 List 中的第二个 Personnel 对象仅将 PersonnelType 作为 id 序列化,因为 PersonnelType (id = 1) 的 id 相同至于 List 中第一个 Personnel 对象中的 PersonnelType。
这是 Jackson 序列化程序的默认行为吗?我没有使用@JsonIdentityReference,因此默认情况下它是错误的。
@JsonIdentityReference 指示是否所有引用的值都被序列化为 ids 的标记(true);或者通过将第一个遇到的引用序列化为 POJO,然后将其序列化为 id (false)。
如何更改序列化,以便在列表中的每个人事对象中返回完整的 PersonnelType 子对象(即使它已经在列表中的前一个人事对象中序列化一次)?
这是我的带有注释的 Personnel 实体:
@Entity
@Table(name = "Personnel", schema = "dbo", catalog = "PSSV2Db")
@EntityListeners(AuditingEntityListener.class)
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id",resolver = EntityIdResolver.class, scope = PersonnelEntity.class)
public class PersonnelEntity extends AuditedEntity<String> {
private Long id;
private Long workforceId;
private String workPhoneNumber;
private String workEmailAddress;
private String UPN;
private String currentPosition;
private Boolean isSponsored;
private LocalDate dateOfSponsorship;
private String sponsorPersonnelId;
private Boolean isLEO;
private Boolean isFERO;
private Boolean requireComputerAndEmailAccess;
private Boolean isPriorityCase;
@Id
@Column(name = "PersonnelId", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Basic
@Column(name = "WorkforceId", nullable = false)
public Long getWorkforceId() {
return workforceId;
}
public void setWorkforceId(Long workforceId) {
this.workforceId = workforceId;
}
@Basic
@Column(name = "WorkPhoneNumber", nullable = true)
public String getWorkPhoneNumber() {
return workPhoneNumber;
}
public void setWorkPhoneNumber(String workPhoneNumber) {
this.workPhoneNumber = workPhoneNumber;
}
@Basic
@Column(name = "WorkEmailAddress", nullable = true)
public String getWorkEmailAddress() {
return workEmailAddress;
}
public void setWorkEmailAddress(String workEmailAddress) {
this.workEmailAddress = workEmailAddress;
}
@Basic
@Column(name = "UPN", nullable = true)
public String getUPN() {
return UPN;
}
public void setUPN(String UPN) {
this.UPN = UPN;
}
@Basic
@Column(name = "CurrentPosition", nullable = true)
public String getCurrentPosition() {
return currentPosition;
}
public void setCurrentPosition(String currentPosition) {
this.currentPosition = currentPosition;
}
@Basic
@Column(name = "IsSponsored", nullable = true)
public Boolean getIsSponsored() {
return isSponsored;
}
public void setIsSponsored(Boolean sponsored) {
this.isSponsored = sponsored;
}
@Basic
@Column(name = "DateOfSponsorship", nullable = true)
public LocalDate getDateOfSponsorship() {
return dateOfSponsorship;
}
public void setDateOfSponsorship(LocalDate dateOfSponsorship) {
this.dateOfSponsorship = dateOfSponsorship;
}
@Basic
@Column(name = "SponsorPersonnelId", nullable = true)
public String getSponsorPersonnelId() {
return sponsorPersonnelId;
}
public void setSponsorPersonnelId(String sponsorPersonnelId) {
this.sponsorPersonnelId = sponsorPersonnelId;
}
@Basic
@Column(name = "IsLEO", nullable = false)
public Boolean getIsLEO() {
return isLEO;
}
public void setIsLEO(Boolean LEO) {
this.isLEO = LEO;
}
@Basic
@Column(name = "IsFERO", nullable = false)
public Boolean getIsFERO() {
return isFERO;
}
public void setIsFERO(Boolean FERO) {
this.isFERO = FERO;
}
@Basic
@Column(name = "RequireComputerAndEmailAddress", nullable = false)
public Boolean getRequireComputerAndEmailAccess() {
return requireComputerAndEmailAccess;
}
public void setRequireComputerAndEmailAccess(Boolean requireComputerAndEmailAccess) {
this.requireComputerAndEmailAccess = requireComputerAndEmailAccess;
}
@Basic
@Column(name = "IsPriorityCase", nullable = false)
public Boolean getIsPriorityCase() {
return isPriorityCase;
}
public void setIsPriorityCase(Boolean isPriorityCase) {
this.isPriorityCase = isPriorityCase;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof PersonnelEntity)) return false;
PersonnelEntity that = (PersonnelEntity) o;
return Objects.equals(getId(), that.getId()) &&
Objects.equals(getWorkforceId(), that.getWorkforceId()) &&
Objects.equals(getWorkPhoneNumber(), that.getWorkPhoneNumber()) &&
Objects.equals(getWorkEmailAddress(), that.getWorkEmailAddress()) &&
Objects.equals(getUPN(), that.getUPN()) &&
Objects.equals(getCurrentPosition(), that.getCurrentPosition()) &&
Objects.equals(getIsSponsored(), that.getIsSponsored()) &&
Objects.equals(getDateOfSponsorship(), that.getDateOfSponsorship()) &&
Objects.equals(getSponsorPersonnelId(), that.getSponsorPersonnelId()) &&
Objects.equals(getIsLEO(), that.getIsLEO()) &&
Objects.equals(getIsFERO(), that.getIsFERO()) &&
Objects.equals(getRequireComputerAndEmailAccess(), that.getRequireComputerAndEmailAccess()) &&
Objects.equals(getIsPriorityCase(), that.getIsPriorityCase());
}
@Override
public int hashCode() {
return Objects.hash(getId(), getWorkforceId(), getWorkPhoneNumber(), getWorkEmailAddress(), getUPN(), getCurrentPosition(), getIsSponsored(), getDateOfSponsorship(), getSponsorPersonnelId(), getIsLEO(), getIsFERO(), getRequireComputerAndEmailAccess(), getIsPriorityCase());
}
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "BuildingId")
public BuildingsEntity getBuilding() {
return building;
}
public void setBuilding(BuildingsEntity building) {
this.building = building;
}
private BuildingsEntity building;
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "PersonnelTypeId")
public PersonnelTypesEntity getPersonnelType() {
return personnelType;
}
public void setPersonnelType(PersonnelTypesEntity personnelType) {
this.personnelType = personnelType;
}
private PersonnelTypesEntity personnelType;
}
这是带有注释的 PersonnelType 实体:
@Entity
@Table(name = "PersonnelTypes", schema = "dbo", catalog = "PSSV2Db")
@EntityListeners(AuditingEntityListener.class)
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id", resolver = EntityIdResolver.class, scope = PersonnelTypesEntity.class)
public class PersonnelTypesEntity extends AuditedEntity<String> {
private long id;
private String description;
private Boolean isActive;
@Id
@Column(name = "PersonnelTypeId", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@Basic
@Column(name = "Description", nullable = true, length = 8000)
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Basic
@Column(name = "IsActive", nullable = false)
public Boolean getIsActive() {
return isActive;
}
public void setIsActive(Boolean isActive) {
this.isActive = isActive;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof PersonnelTypesEntity)) return false;
PersonnelTypesEntity that = (PersonnelTypesEntity) o;
return getId() == that.getId() &&
Objects.equals(getDescription(), that.getDescription()) &&
Objects.equals(getIsActive(), that.getIsActive());
}
@Override
public int hashCode() {
return Objects.hash(getId(), getDescription(), getIsActive());
}
}
【问题讨论】:
-
不,这不是默认设置
-
您能否发布 Personnel 和 PersonnelType 类以及您已应用的所有注释。
-
我在上面添加了它们
-
您正在使用 JsonIdentityInfo。查看它的文档
标签: java json spring serialization jackson