Issue
This is the relevant class:
@Entity
@Table(name = "inventory_data_center")
public class InventoryDataCenterEntity {
@Id
@Column(unique = true)
private String name;
@Column(name = "azure_config", columnDefinition = "TEXT")
@Convert(converter = AzureConfigurationToStringConverter.class)
private List<PodCollection> azureDataCenters;
@Column(name = "monitoringprefix")
private String monitoringPrefix;
public String getName () {
return name;
}
public void setName ( String name ) {
this.name = name;
}
@Cascade(CascadeType.ALL)
public List<PodCollection> getAzureDataCenters () {
return azureDataCenters;
}
public void setAzureDataCenters ( List<PodCollection> azureDataCenters ) {
this.azureDataCenters = azureDataCenters;
}
public String getMonitoringPrefix() {
return monitoringPrefix;
}
public void setMonitoringPrefix(String monitoringPrefix) {
this.monitoringPrefix = monitoringPrefix;
}
}
The InventoryRegionEntity mention in exception is this:
@Entity
@Table(name = "inventory_region")
public class InventoryRegionEntity{
@Id
@Column(unique = true)
@Enumerated(EnumType.STRING)
@NotNull
private Region region;
@ManyToOne
@NotNull
private InventoryDataCenterEntity primaryDC;
@ManyToOne
@JoinColumn(name="secondarydc_name")
private InventoryDataCenterEntity secondaryDC;
private boolean anycast;
public boolean isAnycast () {
return anycast;
}
public void setAnycast ( boolean anycast ) {
this.anycast = anycast;
}
public Region getRegion () {
return this.region;
}
public void setRegion ( Region region ) {
this.region = region;
}
public InventoryDataCenterEntity getPrimaryDC () {
return primaryDC;
}
public void setPrimaryDC ( InventoryDataCenterEntity primaryDC ) {
this.primaryDC = primaryDC;
}
public InventoryDataCenterEntity getSecondaryDC () {
return secondaryDC;
}
public void setSecondaryDC ( InventoryDataCenterEntity secondaryDC ) {
this.secondaryDC = secondaryDC;
}
}
And the exception I get is:
{
"severity": "HIGH",
"message": "org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.gms.model.inventory.InventoryRegionEntity.secondaryDC -> com.gms.model.inventory.InventoryDataCenterEntity; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.gms.model.inventory.InventoryRegionEntity.secondaryDC -> com.gms.model.inventory.InventoryDataCenterEntity",
"requestURI": "/global-management-system/v1/region-inventory",
"type": "org.springframework.dao.InvalidDataAccessApiUsageException",
"stackTrace": null
}
I read on other posts that I should add @Cascade(CascadeType.ALL) before the member or before the collection get method (as in the example above). I also tried CascadeType.PERSIST and CascadeType.SAVE_UPDATE, but got the same result.
Solution
The exception says that InventoryDataCenterEntity
in InventoryRegionEntity
is not found in database and also you are not saving it in database. So that value can be lost. So adding cascadeType.ALL
will save InventoryDataCenterEntity
along with InventoryRegionEntity
if not already saved in database.
Answered By - Jignesh M. Khatri