In my billing application, I have a module that handles signed projects/proposals.
The requirement is to be able to upload supporting documents (such as contract pdfs, excel sheets, emails, etc…) per contract.
I have checked and tried the FileUpload field, but this would upload all files to one storage location.
How can I upload files pertaining to a specific entity, and to a specific record within this entity?
And then how I can view and download the uploaded files per project or proposal.
Please advise on the best approach to achieve this.
Hello!
First of all, you should add a property that will store a list of FileDescriptors. This property should have the OneToMany (or ManyToMany) relationship.
Then you should add the FileUploadField component to your project/proposal edit screen programmatically. In this case, the component will use MANUAL mode and you can add uploaded files to the entity:
uploadField.addFileUploadSucceedListener(event -> {
FileDescriptor fd = uploadField.getFileDescriptor();
try {
fileUploadingAPI.putFileIntoStorage(uploadField.getFileId(), fd);
} catch (FileStorageException e) {
throw new RuntimeException("Error saving file to FileStorage", e);
}
// note that FileDescriptor should be commited before main entity
// save file descriptor to database
FileDescriptor commitedFd = dataSupplier.commit(fd);
project.getSupportingDocuments().add(commitedFd);
});
I am getting the following exception: Exception Description: The attribute [supportingDocs] in entity class [class com.company.billing.entity.Projects] has a mappedBy value of [projects] which does not exist in its owning entity class [class com.haulmont.cuba.core.entity.FileDescriptor]. If the owning entity class is a @MappedSuperclass, this is invalid, and your attribute should reference the correct subclass.
Do I have to edit the core FileDescription entity by adding the needed field? If so, how to do that?
What shall I put in the mappedBy value?
Thanks again for your help.
Your annotation @OneToMany(mappedBy = “projects”, cascade = CascadeType.ALL)
means that FileDescriptor class has a field “projects” when it does not have it.
You can create a new entity class (via Cuba Studio) with a ‘projects’ field that will replace the default FileDescriptor. The only thing you need is to choose FileDescriptor as parent class and tick replace parent checkbox.