I am working on inserting CSV records to Salesforce. I usually do using Bulk API where the types are auto detected and mapped. However, I got into a scenario where I have to upload Documents or Attachments. This below code is what I am trying. Am I going in the right direction?
I have stumbled upon a scenario where the string value is set under record.setField(..)
. This threw the error value not of required type
which expects it to be of the same type of Salesforce object. How can I map the Salesforce Object's type from CSV? Note that I already hold the sObject's details (field, fieldtypes, soaptypes).
I am sure that there could be another way without manually establishing a mapping between Salesforce types and java types (e.g. boolean, but date cannot be done since it is of ISO format).
REST API does accept a json which auto maps the field types. Is there a way that this could be done automatically using SOAP API's Partner jar?
int batchSize = 200;
int bodyIdx = 0;
List<String> keys = new ArrayList<>(ids.keySet());
Path fileDir = SalesforceOptions.restoreFolder.resolve(sObject.getName());
Set<String> binaryFields = new HashSet<>(sObject.getBinaryFields());
List<SObject> records = new ArrayList<>();
String sObjname = sObject.getName();
String bodyField = SalesforceUtility.docFields(sObject).getContent();
// Read the CSV file
try (BufferedReader reader = Files.newBufferedReader(Paths.get(csvPath), StandardCharsets.UTF_8);)
{
// Take a note of the header to keep track of binary field index
CSVRecord header = null;
for (CSVRecord csvRecord : CSVFormat.DEFAULT.withRecordSeparator(System.lineSeparator())
.withQuoteMode(QuoteMode.ALL).parse(reader))
{
if (csvRecord.getRecordNumber() == 1)
{
header = csvRecord;
for (int j = 0; j < header.size(); j++)
{
if (header.get(j).equals(bodyField))
{
bodyIdx = j;
break;
}
}
continue;
}
// Had a logic to put '#' in bulk, undo it; Get the file name
String fileName = csvRecord.get(bodyIdx).replaceFirst("#", "");
Path filePath = fileDir.resolve(fileName);
long fileSize = filePath.toFile().length();
// Record structure
SObject record = new SObject();
// Set the object type
record.setType(sObject.getName());
for (int i = 0; i < header.size(); i++)
{
String fieldName = header.get(i);
if (sObject.hasBinaryfield() && binaryFields.contains(fieldName))
record.setField(fieldName, Base64.getEncoder().encode(Files.readAllBytes(filePath)));
else
{
// FIXME: Probable issue where the field being set is String type
record.setField(fieldName, csvRecord.get(i));
}
}
records.add(record);
if (records.size() % batchSize == 0)
{
if (operationType == OperationEnum.insert)
insert(sObject, records, keys);
else
update(sObject, records, keys);
records.clear();
}
}
if (!records.isEmpty())
{
if (operationType == OperationEnum.insert)
insert(sObject, records, keys);
else
update(sObject, records, keys);
}
}
Date
in Salesforce, but the string you are passing in from the CSV isn't in the correct format.