I have configured my Camumda instance to use JSON serialization via the:
/server/apache-tomcat-9.0.52/conf/bpm-platform.xml
Adding:
<properties>
<property name="history">full</property>
<property name="databaseSchemaUpdate">true</property>
<property name="authorizationEnabled">true</property>
<property name="jobExecutorDeploymentAware">true</property>
<property name="historyCleanupBatchWindowStartTime">00:01</property>
<property name="defaultSerializationFormat">application/json</property> <<------This line
</properties>
I then write the variable thusly:
public CustomerApplication getCustomerApplication(DelegateExecution execution) {
CustomerApplication customerApplication = (CustomerApplication) execution.getVariable(ProcessConstants.VAR_CUSTOMER_APPLICATION);
if (customerApplication == null) {
customerApplication = getDefaultCustomerApplication();
setCustomerApplication(execution, customerApplication);
}
return customerApplication;
}
public void setCustomerApplication(DelegateExecution execution, CustomerApplication customerApplication) {
execution.setVariable(ProcessConstants.VAR_CUSTOMER_APPLICATION, customerApplication);
}
When the variable is stored the cockpit sees it as such:
Opening the variable we see it serialises and writes successfully serialized:
However the deserialisation view seems to have an error:
I am also having an issue in the embedded forms with it.
I load the variable from the form like this:
<script cam-script type="text/form-script">
var customerApplication = $scope.customerApplication = {
};
camForm.on('form-loaded', function() {
camForm.variableManager.fetchVariable('customerApplication');
});
camForm.on('variables-fetched', function() {
$scope.customerApplication = camForm.variableManager.variable('customerApplication').value;
});
</script>
And it bind no problem to the form.
However when I click the “Complete” button I get the following error:
The class itself is complex, and was generated from the OpenAPI spec generator.
Here is the top level class for completion:
package za.co.REDACTED.flow.model;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import za.co.REDACTED.flow.model.BalanceSheetAssets;
import za.co.REDACTED.flow.model.BalanceSheetLiabilities;
import za.co.REDACTED.flow.model.BankingDetails;
import za.co.REDACTED.flow.model.ContactInformation;
import za.co.REDACTED.flow.model.EmploymentDetails;
import za.co.REDACTED.flow.model.Expenditure;
import za.co.REDACTED.flow.model.Income;
import za.co.REDACTED.flow.model.Marketing;
import za.co.REDACTED.flow.model.NextOfKin;
import za.co.REDACTED.flow.model.PersonalDetails;
import za.co.REDACTED.flow.model.VehicleInformation;
import org.openapitools.jackson.nullable.JsonNullable;
import java.io.Serializable;
import javax.validation.Valid;
import javax.validation.constraints.*;
/**
* CustomerApplication
*/
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-01-05T12:46:27.757310+02:00[Africa/Johannesburg]")
public class CustomerApplication implements Serializable {
private static final long serialVersionUID = 1L;
@JsonProperty("applicationId")
private String applicationId;
@JsonProperty("applicationKey")
private String applicationKey;
@JsonProperty("quoteDocumentURL")
private String quoteDocumentURL;
@JsonProperty("finalized")
private Boolean finalized;
@JsonProperty("vehicleInformation")
private VehicleInformation vehicleInformation;
@JsonProperty("personalDetails")
private PersonalDetails personalDetails;
@JsonProperty("contactInformation")
private ContactInformation contactInformation;
@JsonProperty("nextOfKin")
private NextOfKin nextOfKin;
@JsonProperty("employmentDetails")
private EmploymentDetails employmentDetails;
@JsonProperty("bankingDetails")
private BankingDetails bankingDetails;
@JsonProperty("income")
private Income income;
@JsonProperty("expenditure")
private Expenditure expenditure;
@JsonProperty("balanceSheetAssets")
private BalanceSheetAssets balanceSheetAssets;
@JsonProperty("balanceSheetLiabilities")
private BalanceSheetLiabilities balanceSheetLiabilities;
@JsonProperty("marketing")
private Marketing marketing;
public CustomerApplication applicationId(String applicationId) {
this.applicationId = applicationId;
return this;
}
/**
* Application ID
* @return applicationId
*/
@ApiModelProperty(required = true, value = "Application ID")
@NotNull
public String getApplicationId() {
return applicationId;
}
public void setApplicationId(String applicationId) {
this.applicationId = applicationId;
}
public CustomerApplication applicationKey(String applicationKey) {
this.applicationKey = applicationKey;
return this;
}
/**
* Application Key
* @return applicationKey
*/
@ApiModelProperty(required = true, value = "Application Key")
@NotNull
public String getApplicationKey() {
return applicationKey;
}
public void setApplicationKey(String applicationKey) {
this.applicationKey = applicationKey;
}
public CustomerApplication quoteDocumentURL(String quoteDocumentURL) {
this.quoteDocumentURL = quoteDocumentURL;
return this;
}
/**
* Quotation Document Url
* @return quoteDocumentURL
*/
@ApiModelProperty(value = "Quotation Document Url")
public String getQuoteDocumentURL() {
return quoteDocumentURL;
}
public void setQuoteDocumentURL(String quoteDocumentURL) {
this.quoteDocumentURL = quoteDocumentURL;
}
public CustomerApplication finalized(Boolean finalized) {
this.finalized = finalized;
return this;
}
/**
* Application Form Has Been Finalized
* @return finalized
*/
@ApiModelProperty(required = true, value = "Application Form Has Been Finalized")
@NotNull
public Boolean getFinalized() {
return finalized;
}
public void setFinalized(Boolean finalized) {
this.finalized = finalized;
}
public CustomerApplication vehicleInformation(VehicleInformation vehicleInformation) {
this.vehicleInformation = vehicleInformation;
return this;
}
/**
* Get vehicleInformation
* @return vehicleInformation
*/
@ApiModelProperty(required = true, value = "")
@NotNull
@Valid
public VehicleInformation getVehicleInformation() {
return vehicleInformation;
}
public void setVehicleInformation(VehicleInformation vehicleInformation) {
this.vehicleInformation = vehicleInformation;
}
public CustomerApplication personalDetails(PersonalDetails personalDetails) {
this.personalDetails = personalDetails;
return this;
}
/**
* Get personalDetails
* @return personalDetails
*/
@ApiModelProperty(required = true, value = "")
@NotNull
@Valid
public PersonalDetails getPersonalDetails() {
return personalDetails;
}
public void setPersonalDetails(PersonalDetails personalDetails) {
this.personalDetails = personalDetails;
}
public CustomerApplication contactInformation(ContactInformation contactInformation) {
this.contactInformation = contactInformation;
return this;
}
/**
* Get contactInformation
* @return contactInformation
*/
@ApiModelProperty(required = true, value = "")
@NotNull
@Valid
public ContactInformation getContactInformation() {
return contactInformation;
}
public void setContactInformation(ContactInformation contactInformation) {
this.contactInformation = contactInformation;
}
public CustomerApplication nextOfKin(NextOfKin nextOfKin) {
this.nextOfKin = nextOfKin;
return this;
}
/**
* Get nextOfKin
* @return nextOfKin
*/
@ApiModelProperty(required = true, value = "")
@NotNull
@Valid
public NextOfKin getNextOfKin() {
return nextOfKin;
}
public void setNextOfKin(NextOfKin nextOfKin) {
this.nextOfKin = nextOfKin;
}
public CustomerApplication employmentDetails(EmploymentDetails employmentDetails) {
this.employmentDetails = employmentDetails;
return this;
}
/**
* Get employmentDetails
* @return employmentDetails
*/
@ApiModelProperty(required = true, value = "")
@NotNull
@Valid
public EmploymentDetails getEmploymentDetails() {
return employmentDetails;
}
public void setEmploymentDetails(EmploymentDetails employmentDetails) {
this.employmentDetails = employmentDetails;
}
public CustomerApplication bankingDetails(BankingDetails bankingDetails) {
this.bankingDetails = bankingDetails;
return this;
}
/**
* Get bankingDetails
* @return bankingDetails
*/
@ApiModelProperty(required = true, value = "")
@NotNull
@Valid
public BankingDetails getBankingDetails() {
return bankingDetails;
}
public void setBankingDetails(BankingDetails bankingDetails) {
this.bankingDetails = bankingDetails;
}
public CustomerApplication income(Income income) {
this.income = income;
return this;
}
/**
* Get income
* @return income
*/
@ApiModelProperty(required = true, value = "")
@NotNull
@Valid
public Income getIncome() {
return income;
}
public void setIncome(Income income) {
this.income = income;
}
public CustomerApplication expenditure(Expenditure expenditure) {
this.expenditure = expenditure;
return this;
}
/**
* Get expenditure
* @return expenditure
*/
@ApiModelProperty(required = true, value = "")
@NotNull
@Valid
public Expenditure getExpenditure() {
return expenditure;
}
public void setExpenditure(Expenditure expenditure) {
this.expenditure = expenditure;
}
public CustomerApplication balanceSheetAssets(BalanceSheetAssets balanceSheetAssets) {
this.balanceSheetAssets = balanceSheetAssets;
return this;
}
/**
* Get balanceSheetAssets
* @return balanceSheetAssets
*/
@ApiModelProperty(required = true, value = "")
@NotNull
@Valid
public BalanceSheetAssets getBalanceSheetAssets() {
return balanceSheetAssets;
}
public void setBalanceSheetAssets(BalanceSheetAssets balanceSheetAssets) {
this.balanceSheetAssets = balanceSheetAssets;
}
public CustomerApplication balanceSheetLiabilities(BalanceSheetLiabilities balanceSheetLiabilities) {
this.balanceSheetLiabilities = balanceSheetLiabilities;
return this;
}
/**
* Get balanceSheetLiabilities
* @return balanceSheetLiabilities
*/
@ApiModelProperty(required = true, value = "")
@NotNull
@Valid
public BalanceSheetLiabilities getBalanceSheetLiabilities() {
return balanceSheetLiabilities;
}
public void setBalanceSheetLiabilities(BalanceSheetLiabilities balanceSheetLiabilities) {
this.balanceSheetLiabilities = balanceSheetLiabilities;
}
public CustomerApplication marketing(Marketing marketing) {
this.marketing = marketing;
return this;
}
/**
* Get marketing
* @return marketing
*/
@ApiModelProperty(required = true, value = "")
@NotNull
@Valid
public Marketing getMarketing() {
return marketing;
}
public void setMarketing(Marketing marketing) {
this.marketing = marketing;
}
@Override
public boolean equals(java.lang.Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
CustomerApplication customerApplication = (CustomerApplication) o;
return Objects.equals(this.applicationId, customerApplication.applicationId) &&
Objects.equals(this.applicationKey, customerApplication.applicationKey) &&
Objects.equals(this.quoteDocumentURL, customerApplication.quoteDocumentURL) &&
Objects.equals(this.finalized, customerApplication.finalized) &&
Objects.equals(this.vehicleInformation, customerApplication.vehicleInformation) &&
Objects.equals(this.personalDetails, customerApplication.personalDetails) &&
Objects.equals(this.contactInformation, customerApplication.contactInformation) &&
Objects.equals(this.nextOfKin, customerApplication.nextOfKin) &&
Objects.equals(this.employmentDetails, customerApplication.employmentDetails) &&
Objects.equals(this.bankingDetails, customerApplication.bankingDetails) &&
Objects.equals(this.income, customerApplication.income) &&
Objects.equals(this.expenditure, customerApplication.expenditure) &&
Objects.equals(this.balanceSheetAssets, customerApplication.balanceSheetAssets) &&
Objects.equals(this.balanceSheetLiabilities, customerApplication.balanceSheetLiabilities) &&
Objects.equals(this.marketing, customerApplication.marketing);
}
@Override
public int hashCode() {
return Objects.hash(applicationId, applicationKey, quoteDocumentURL, finalized, vehicleInformation, personalDetails, contactInformation, nextOfKin, employmentDetails, bankingDetails, income, expenditure, balanceSheetAssets, balanceSheetLiabilities, marketing);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class CustomerApplication {\n");
sb.append(" applicationId: ").append(toIndentedString(applicationId)).append("\n");
sb.append(" applicationKey: ").append(toIndentedString(applicationKey)).append("\n");
sb.append(" quoteDocumentURL: ").append(toIndentedString(quoteDocumentURL)).append("\n");
sb.append(" finalized: ").append(toIndentedString(finalized)).append("\n");
sb.append(" vehicleInformation: ").append(toIndentedString(vehicleInformation)).append("\n");
sb.append(" personalDetails: ").append(toIndentedString(personalDetails)).append("\n");
sb.append(" contactInformation: ").append(toIndentedString(contactInformation)).append("\n");
sb.append(" nextOfKin: ").append(toIndentedString(nextOfKin)).append("\n");
sb.append(" employmentDetails: ").append(toIndentedString(employmentDetails)).append("\n");
sb.append(" bankingDetails: ").append(toIndentedString(bankingDetails)).append("\n");
sb.append(" income: ").append(toIndentedString(income)).append("\n");
sb.append(" expenditure: ").append(toIndentedString(expenditure)).append("\n");
sb.append(" balanceSheetAssets: ").append(toIndentedString(balanceSheetAssets)).append("\n");
sb.append(" balanceSheetLiabilities: ").append(toIndentedString(balanceSheetLiabilities)).append("\n");
sb.append(" marketing: ").append(toIndentedString(marketing)).append("\n");
sb.append("}");
return sb.toString();
}
/**
* Convert the given object to string with each line indented by 4 spaces
* (except the first line).
*/
private String toIndentedString(java.lang.Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}
EDIT:
This is the serialized value:
{
"applicationId": "2",
"applicationKey": "126d6c3e-d731-4c1d-8ef3-89d7fc58d48c",
"quoteDocumentUrl": "REDACTED",
"finalized": null,
"vehicleInformation": {
"goodsDescription": null,
"mmCode": "24010141",
"make": "HINO",
"model": "HINO 300 SERIESHINO 300 614 SWB (EU3)",
"dealership": "HINO INDONGO",
"dealerTelephone": "REDACTED",
"refNo": "REDACTED",
"indongoFAndIOnly": null,
"emailFAndI": null,
"cashPriceVatIncl": null,
"tradePrice": null,
"cashPrice": null,
"extras": null,
"fuelling": null,
"licenseRegFee": null,
"subTotal": null,
"vat": null,
"insurance": null,
"stamps": null,
"other": null,
"lessDeposit": null,
"amountFinanced": 444349,
"valueAddedWarrantees": null,
"valueAddedPaintProtection": null,
"valueAddedServicePlan": null,
"valueAddedSafetyFilm": null,
"valueAddedCarCareVoucher": null,
"valueAddedTotal": null
},
"personalDetails": {
"nationalityType": null,
"nationalityOther": null,
"statusIfOtherNationality": null,
"timeInNamibia": {
"present": false
},
"title": null,
"surname": "REDACTED",
"firstNames": "",
"idNumber": null,
"previousSurname": null,
"initials": null,
"gender": null,
"placeOfBirth": null,
"nationality": null,
"maritalStatus": null,
"marriageType": null,
"marriageDate": null
},
"contactInformation": {
"homeAddress": "REDACTED",
"homeAddressPostCode": "10005",
"periodAtAddress": null,
"postalAddress": "REDACTED",
"postalAddressPostCode": "REDACTED",
"residentialStatus": null,
"countryOfResidence": null,
"residentialAddress": null,
"telephoneHome": null,
"telephoneWork": null,
"telephoneCell": "REDACTED",
"email": "",
"statusUS": null,
"hasGuarantor": null,
"guarantorName": null
},
"nextOfKin": {
"spouseName": null,
"spouseIDNumber": null,
"nextOfKinName": null,
"relationship": null,
"nextOfKinAddress": null,
"nextOfKinTelephone": null
},
"employmentDetails": {
"employerName": null,
"yearWithEmployer": null,
"industryType": null,
"occupation": null,
"salaryDay": null
},
"bankingDetails": {
"bankName": null,
"branch": null,
"branchCode": null,
"nameOfAccountHolder": null,
"accountNumber": null,
"accountType": null,
"sourceOfIncomeSalaryEarner": null,
"sourceOfIncomeSelfEmployed": null,
"sourceOfIncomeCommission": null,
"sourceOfIncomeDirector": null,
"sourceOfIncomePension": null,
"sourceOfIncomeMaintenance": null,
"sourceOfIncomeCourtOrder": null,
"sourceOfIncomeMemberOfCorporation": null
},
"income": {
"netSalary": {
"present": false
},
"netSalarySpouse": {
"present": false
},
"rentalIncome": {
"present": false
},
"grossSalary": {
"present": false
},
"otherGrossIncome": {
"present": false
}
},
"expenditure": {
"houseInstallment": {
"present": false
},
"personalLoan": {
"present": false
},
"otherLoanRepayment": {
"present": false
},
"articleFinance": {
"present": false
},
"creditAgreementRepayment": {
"present": false
},
"overdraftInterest": {
"present": false
},
"clothingAccounts": {
"present": false
},
"insurance": {
"present": false
},
"lifeAssurance": {
"present": false
},
"utilities": {
"present": false
},
"ratesAndTaxes": {
"present": false
},
"domesticSalaries": {
"present": false
},
"telephone": {
"present": false
},
"householdExpenses": {
"present": false
},
"groceries": {
"present": false
},
"children": {
"present": false
},
"maintenance": {
"present": false
},
"fuel": {
"present": false
},
"medicalAid": {
"present": false
},
"creditLifeProtection": {
"present": false
},
"stopOrders": {
"present": false
},
"subscriptionServices": {
"present": false
},
"security": {
"present": false
},
"taxation": {
"present": false
},
"pensionContributions": {
"present": false
},
"retirementAnnuityPremiums": {
"present": false
},
"furnitureAccountRepayments": {
"present": false
},
"schoolFees": {
"present": false
},
"entertainment": {
"present": false
},
"other": {
"present": false
}
},
"balanceSheetAssets": {
"fixedProperty": {
"present": false
},
"fixedPropertySpecify": null,
"vehicles": {
"present": false
},
"vehiclesSpecify": null,
"cash": {
"present": false
},
"cashSpecify": null,
"investments": {
"present": false
},
"investmentsSpecify": null,
"other": {
"present": false
},
"othersSpecify": null
},
"balanceSheetLiabilities": {
"mortgage": {
"present": false
},
"mortgageInstitution": null,
"hirePurchase": {
"present": false
},
"hirePurchaseInstitution": null,
"overdraft": {
"present": false
},
"overdraftInstitution": null,
"retailAccounts": {
"present": false
},
"retailAccountsInstitution": null,
"other": {
"present": false
},
"otherInstitution": null
},
"marketing": {
"specialOffers": null,
"exclusiveOffers": null,
"researchOrganisations": null,
"preferredCommunicationEmail": null,
"preferredCommunicationSMS": null,
"preferredCommunicationDirectMail": null,
"preferredCommunicationTelephone": null,
"alternateCommunication": null
}
}
EDIT 2:
After modifying the OpenAPI spec to remove JSONNullable types the new Objects seem to allow the workflow to continue, but I still have the saving issue where any changes are not persisted back into the model on save on the user task.
This is the new JSON:
{
"applicationId": "2",
"applicationKey": "04ce5542-7588-407d-ba5e-13ec449dfb82",
"quoteDocumentUrl": "REDACTED",
"finalized": null,
"vehicleInformation": {
"goodsDescription": null,
"mmCode": "24010141",
"make": "HINO",
"model": "HINO 300 SERIESHINO 300 614 SWB (EU3)",
"dealership": "HINO INDONGO",
"dealerTelephone": "REDACTED",
"refNo": "REDACTED",
"indongoFAndIOnly": null,
"emailFAndI": null,
"cashPriceVatIncl": null,
"tradePrice": null,
"cashPrice": null,
"extras": null,
"fuelling": null,
"licenseRegFee": null,
"subTotal": null,
"vat": null,
"insurance": null,
"stamps": null,
"other": null,
"lessDeposit": null,
"amountFinanced": 444349,
"valueAddedWarrantees": null,
"valueAddedPaintProtection": null,
"valueAddedServicePlan": null,
"valueAddedSafetyFilm": null,
"valueAddedCarCareVoucher": null,
"valueAddedTotal": null
},
"personalDetails": {
"nationalityType": null,
"nationalityOther": null,
"statusIfOtherNationality": null,
"timeInNamibia": null,
"title": null,
"surname": "REDACTED",
"firstNames": "",
"idNumber": null,
"previousSurname": null,
"initials": null,
"gender": null,
"placeOfBirth": null,
"nationality": null,
"maritalStatus": null,
"marriageType": null,
"marriageDate": null
},
"contactInformation": {
"homeAddress": "REDACTEDK",
"homeAddressPostCode": "REDACTED",
"periodAtAddress": null,
"postalAddress": "REDACTED",
"postalAddressPostCode": "10005",
"residentialStatus": null,
"countryOfResidence": null,
"residentialAddress": null,
"telephoneHome": null,
"telephoneWork": null,
"telephoneCell": "REDACTED",
"email": "",
"statusUS": null,
"hasGuarantor": null,
"guarantorName": null
},
"nextOfKin": {
"spouseName": null,
"spouseIDNumber": null,
"nextOfKinName": null,
"relationship": null,
"nextOfKinAddress": null,
"nextOfKinTelephone": null
},
"employmentDetails": {
"employerName": null,
"yearWithEmployer": null,
"industryType": null,
"occupation": null,
"salaryDay": null
},
"bankingDetails": {
"bankName": null,
"branch": null,
"branchCode": null,
"nameOfAccountHolder": null,
"accountNumber": null,
"accountType": null,
"sourceOfIncomeSalaryEarner": null,
"sourceOfIncomeSelfEmployed": null,
"sourceOfIncomeCommission": null,
"sourceOfIncomeDirector": null,
"sourceOfIncomePension": null,
"sourceOfIncomeMaintenance": null,
"sourceOfIncomeCourtOrder": null,
"sourceOfIncomeMemberOfCorporation": null
},
"income": {
"netSalary": null,
"netSalarySpouse": null,
"rentalIncome": null,
"grossSalary": null,
"otherGrossIncome": null
},
"expenditure": {
"houseInstallment": null,
"personalLoan": null,
"otherLoanRepayment": null,
"articleFinance": null,
"creditAgreementRepayment": null,
"overdraftInterest": null,
"clothingAccounts": null,
"insurance": null,
"lifeAssurance": null,
"utilities": null,
"ratesAndTaxes": null,
"domesticSalaries": null,
"telephone": null,
"householdExpenses": null,
"groceries": null,
"children": null,
"maintenance": null,
"fuel": null,
"medicalAid": null,
"creditLifeProtection": null,
"stopOrders": null,
"subscriptionServices": null,
"security": null,
"taxation": null,
"pensionContributions": null,
"retirementAnnuityPremiums": null,
"furnitureAccountRepayments": null,
"schoolFees": null,
"entertainment": null,
"other": null
},
"balanceSheetAssets": {
"fixedProperty": null,
"fixedPropertySpecify": null,
"vehicles": null,
"vehiclesSpecify": null,
"cash": null,
"cashSpecify": null,
"investments": null,
"investmentsSpecify": null,
"other": null,
"othersSpecify": null
},
"balanceSheetLiabilities": {
"mortgage": null,
"mortgageInstitution": null,
"hirePurchase": null,
"hirePurchaseInstitution": null,
"overdraft": null,
"overdraftInstitution": null,
"retailAccounts": null,
"retailAccountsInstitution": null,
"other": null,
"otherInstitution": null
},
"marketing": {
"specialOffers": null,
"exclusiveOffers": null,
"researchOrganisations": null,
"preferredCommunicationEmail": null,
"preferredCommunicationSMS": null,
"preferredCommunicationDirectMail": null,
"preferredCommunicationTelephone": null,
"alternateCommunication": null
}
}
Thanks you for any help in advance