I am trying to save a file and recreate it at a different step in the process. Because the files are too big to save as a variable (TEXT_ VARCHAR(4000)) I am sending it in as a JSON object. Now the problem is that when I access the file, the getVariable function saves the response as a String and sends it to the database (the reason I think it is being saved is due to this thread TaskServiceImpl.getVariables results into db insertion of history table data) and then it runs into an error that the variable is too long. Is there a way to save it to the database during the get as a JSON object or to completely avoid it being saved to the database?
Saving the file
String pdfFile = readPdf(filePath + currentFilename);
JsonToObject setObject=new JsonToObject("send file", pdfFile);
ObjectMapper mapper = new ObjectMapper();
String jsonString = mapper.writeValueAsString(setObject);
JsonValue jsonValue = SpinValues.jsonValue(jsonString).create();
delegateExecution.setVariable("embeddedText", jsonValue);
Accessing the file
SpinJsonNode jsonResponse = JSON(delegateExecution.getVariable("embeddedText"));
SpinJsonNode bodyProperty = jsonResponse.prop("body");
String fileContents=bodyProperty.stringValue();
Caused by: org.camunda.bpm.engine.ProcessEngineException: ENGINE-03004 Exception while executing Database Operation ‘INSERT HistoricVariableUpdateEventEntity[5017061b-160b-11ec-8148-0242447d15b3]’ with message ’
Error flushing statements. Cause: org.apache.ibatis.executor.BatchExecutorException: org.camunda.bpm.engine.impl.persistence.entity.HistoricDetailEntity.insertHistoricVariableUpdateEvent (batch index #3) failed. 2 prior sub executor(s) completed successfully, but will be rolled back. Cause: org.h2.jdbc.JdbcBatchUpdateException: Value too long for column “TEXT_ VARCHAR(4000)”: “'{”“destination”“:”“send file”“,”“body”“:”“JVBERi0xLjQKJdPr6eEKMSAwIG9iago8PC9UaXRsZSAoRW1wdHkgZmlsZSkKL1Byb2R1Y2VyIChTa2lhL1BERiBtOTUg… (15665)”; SQL statement:
insert into ACT_HI_DETAIL
Caused by: org.h2.jdbc.JdbcBatchUpdateException: Value too long for column “TEXT_
VARCHAR(4000)”: “'{”“destination”“:”“send file”“,”“body”“:”“JVBERi0xLjQKJdPr6eEKMSAwIG9iago8PC9UaXRsZSAoRW1wdHkgZmlsZSkKL1Byb2R1Y2VyIChTa2lhL1BERiBtOTUg… (15665)”; SQL statement:
insert into ACT_HI_DETAIL
I am still pretty new to Camunda, so if there is a better way to store and recreate files in Camunda, I am very open to alternatives
Hey there,
I think there is a better approach to what you’re doing.
Camunda does support storing files the way they are, what you’re trying to achieve is to implement your custom serialization technique…
Here’s what you can do:
Here you can set the resource name and the type of your file. Pretty straightforward if you ask me…
https://docs.camunda.org/manual/7.8/user-guide/process-engine/variables/#file-values
Hope this helps!
Goodluck
Hey @maroun_ayle
That definitely seems to be a better way of doing it, although one question, how do you set the runtimeService? At the moment I am accessing it via a JavaDelegate so that it integrates with the BPNM process, is there another way that you should create it?
Thank you it does seem to be in the right vein
If you’re working with camunda inside a springboot application the runtimeService is a singleton bean that you can access anywhere in your application.
How are you currently using Camunda ?
It is not showing up as a variable I can access. I created a spring boot application with a class that implements a java delegate and from that point, I am trying to embed the file\
@Named
public class EmbedPDF implements JavaDelegate {
public void execute(DelegateExecution delegateExecution) {
String filePath = "example path;
String currentFilename = “example_file.txt”;
FileValue typedFileValue = Variables
.fileValue(currentFilename)
.file(new File(filePath))
.mimeType(“text/plain”)
.encoding(“UTF-8”)
.create();
runtimeService.setVariable(delegateExecution.getId(), “fileVariable”, typedFileValue);
}
Where
java: cannot find symbol
symbol: variable runtimeService
you can get it this way if you want:
RuntimeService runtimeService = delegateExecution.getProcessEngine().getRuntimeService();
Are you then supposed to be able to access the same runtimeService in another java delegate when you call it in a different process?
@Named
public class outputPdf implements JavaDelegate {
@Override
public void execute(DelegateExecution delegateExecution) throws IOException {
RuntimeService runtimeService = delegateExecution.getProcessEngine().getRuntimeService();
FileValue retrievedTypedFileValue = runtimeService.getVariableTyped(delegateExecution.getId(), “fileVariable”);
java.lang.ClassCastException: class org.camunda.bpm.engine.variable.impl.value.NullValueImpl cannot be cast to class org.camunda.bpm.engine.variable.value.FileValue (org.camunda.bpm.engine.variable.impl.value.NullValueImpl and org.camunda.bpm.engine.variable.value.FileValue are in unnamed module of loader ‘app’)
at com.example.workflow.outputPdf.execute(outputPdf.java:26) ~[classes/:na]