Я портирую свой прежний код на приложение Spring boot + angular, которое раньше было spring + angular js. В моем pojo ленивые отношения @ManyToOne. Когда я пытаюсь создать объект DTO из исходного объекта, дочерний объект внутри оригинального объекта при отправке клиенту становится пустым. В моем унаследованном приложении тот же код работает отлично.
Если я делаю это нетерпеливым или вызываю sysout для этого дочернего элемента перед созданием DTO, то это работает, вероятно, потому, что getters дочернего объекта вызывается внутренне.
Родительский объект
public class ComponentInfo implements Serializable{
private static final long serialVersionUID = -1135710750835719391L;
@Id
@Column(name="TAGGING_KEY")
private String taggingKey;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "COMPONENT_CONFIG_ID",nullable = true)
private ReportComponentConfig componentConfig;
@Column(name = "DESCRIPTION", length = 200)
private String description;
@Column(name = "ORIGINAL_FILE_NAME",length=50)
private String originalFileName;
@Column(name = "OVERRIDE_DOCUMENT")
private Boolean overrideDocument = false;
@Column(name = "START_DATE")
private Date startDate;
@OneToMany(mappedBy="componentInfo",cascade=CascadeType.ALL,orphanRemoval=true)
private List<TransactionComponentInfo> transactionComponentInfo = new ArrayList<>(0);
@Column(name = "SHOW_GLOBAL")
private Boolean showGlobal = false;
}
Дочерний объект
public class ReportComponentConfig {
@Id
@TableGenerator(name = "COMPONENT_CONFIG_ID", table = "ID_GENERATOR", pkColumnName = "GEN_KEY", valueColumnName = "GEN_VALUE", pkColumnValue = "COMPONENT_CONFIG_ID", allocationSize = 1, initialValue = 1)
@GeneratedValue(strategy = GenerationType.TABLE, generator = "COMPONENT_CONFIG_ID")
@Column(name = "COMPONENT_CONFIG_ID", unique = true, nullable = false)
private int id;
@Column(name = "NAME", nullable = false, length = 200)
private String name;
@Column(name = "TAG", nullable = false, length = 200)
private String tag;
@Column(name = "COMP_CONFIG", nullable = false, columnDefinition = "VARCHAR(MAX)")
private String config;
@Column(name = "PUBLISHED_CONFIG", columnDefinition = "VARCHAR(MAX)")
private String publishedConfig;
@Column(name = "IS_PUBLISHED")
private boolean published = false;
@ManyToOne
@JoinColumn(name = "COMPONENT_ID", nullable = false)
private Component component;
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "CONFIG_REPORT_MAPPING", joinColumns = @JoinColumn(name = "COMPONENT_CONFIG_ID"))
@Column(name = "REPORT_ID")
private Set<Long> reports = new HashSet<>(0);
@ElementCollection(fetch = FetchType.LAZY)
@CollectionTable(name = "CONFIG_TRANSACTION_MAPPING", joinColumns = @JoinColumn(name = "COMPONENT_CONFIG_ID"))
@Column(name = "TRANSACTION_ID")
private Set<Long> transactions = new HashSet<>(0);
@Column(name = "VIEWS", columnDefinition = "VARCHAR(MAX)")
private String views;
}
DTO
public class ComponentInfoDTO implements Cloneable {
private ReportComponentConfig componentConfig;
private String taggingKey;
private String description;
private String originalFileName;
private Date startDate;
private Boolean overrideDocument;
private Boolean showGlobal;
private ComponentInfoDTO parentComponentInfo;
public ComponentInfoDTO() {
}
public ComponentInfoDTO(ComponentInfo ci, TransactionComponentInfo transactionComponentInfo) {
this.componentConfig = ci.getComponentConfig();//this is object is null
this.taggingKey = ci.getTaggingKey();
this.description = ci.getDescription();
this.originalFileName = ci.getOriginalFileName();
this.startDate = ci.getStartDate();
this.overrideDocument = ci.getOverrideDocument();
this.showGlobal = ci.getShowGlobal();
if (transactionComponentInfo != null) {
this.parentComponentInfo = this.clone();
this.startDate = transactionComponentInfo.getStartDate();
this.overrideDocument = transactionComponentInfo.getOverrideDocument();
this.description = transactionComponentInfo.getDescription();
this.originalFileName = transactionComponentInfo.getOriginalFileName();
this.showGlobal = true;
}
}
}
Новое кодовое изображение
Старый код изображения
Редактировать: оба одинаковы, но в старом случае я получаю дочерний объект на стороне клиента, а в новом случае я получаю ноль.
Это данные, которые я получаю в моем старом приложении с ленивым init
[ {
"componentConfig" : {
"id" : 3,
"name" : "Monthly Origination By Region",
"tag" : "CHART_monthlyOriginationByRegion",
"config" : "xyz",
"published" : true,
"component" : {
"id" : "CHART",
"name" : "Chart",
"defaultConfig" : null,
"htmlTag" : "<chart></chart>",
"filePath" : "chart/chart.component.js",
"dependentScriptsSrc" : [ ],
"dependencies" : null
},
"reports" : [ 3 ],
"transactions" : [ 2 ],
"views" : "{\"monthlyOriginationByRegion\": {\"key\": \"MONTHLY_ORIGINATION_BY_REGION\"}}"
},
"taggingKey" : "3",
"description" : "asdfasd\nasdfadf",
"originalFileName" : "Citi Tape - 2141 - GEBL0501 - 2019 Oct 04.xlsm",
"startDate" : "2019-10-28T18:30:00.000+0000",
"overrideDocument" : true,
"showGlobal" : true,
"parentComponentInfo" : null
} ]
Это данные в новом приложении
[ {
"componentConfig" : null,
"taggingKey" : "3",
"description" : "asdfasd\nasdfadf",
"originalFileName" : "Citi Tape - 2141 - GEBL0501 - 2019 Oct 04.xlsm",
"startDate" : "2019-10-28T18:30:00.000+0000",
"overrideDocument" : true,
"showGlobal" : true,
"parentComponentInfo" : null
} ]
Конфигурация компонента не должна быть нулевой, если она сделананетерпеливый выбор, это работает в новом приложении, но в моем более старом приложении это работает с отложенной выборкой.