Have tried some variants to this code and always get the same result.
If uploading files through the External Files in the Administration menu, it works fine, so doesn’t seem to be any config setting. Somehow the code snippets extracted from the internet don’t work in my case.
Hi,
I have the same problem. I found reason in LocalFileExchangeServiceBean in downloadFile method. This function try to load not existed FileDescriptor (new)
@Override
public InputStream downloadFile(FileDescriptor fileDescriptor) throws FileStorageException {
FileDescriptor descriptor;
try {
// FileDescriptor must be available for the current user and be non deleted
descriptor = dataManager.secure().reload(fileDescriptor, View.LOCAL);
} catch (EntityAccessException e) {
throw new FileStorageException(FileStorageException.Type.FILE_NOT_FOUND, fileDescriptor.getName(), e);
}
return fileStorage.openStream(descriptor);
}
I created extended version of this bean (in Kotlin)
class ExtLocalFileExchangeServiceBean : LocalFileExchangeServiceBean() {@Inject
private lateinit var entityStates: EntityStates
@Throws(FileStorageException::class)
override fun downloadFile(fileDescriptor: FileDescriptor): InputStream {
val descriptor: FileDescriptor
descriptor = try {
// FileDescriptor must be available for the current user and be non deleted
if (!entityStates.isNew(fileDescriptor)) {
dataManager.secure().reload(fileDescriptor, View.LOCAL)
} else {
fileDescriptor
}
} catch (e: EntityAccessException) {
throw FileStorageException(FileStorageException.Type.FILE_NOT_FOUND, fileDescriptor.name, e)
}
return fileStorage.openStream(descriptor)
}}
The FileNotFoundException appears because the FileDescriptor entity has not been saved in the data store. Try adding dataManager.commit(fileDescriptor) after the fileUploadingAPI.putFileIntoStorage(fileId, fileDescriptor) line.
You can find an example of using the FileUploadDialog in the documentation.
it works. However to understand a bit better what’s going on… if I call
dataManager.commit(fileDescriptor)
what do I exactly do behind the scene? execute an isolated transaction only for the file?
after trying it succeeded, also because the main transaction (with the host standardeditor) wasn’t affected. Don’t quite understand yet the scope of some actions of the dataManager. If you can shed some light it would be great.
Mark as solved. Many thanks for your valuable help.
commit(CommitContext) – saves a set of entities passed in CommitContext to the database. The method returns the set of entity instances returned by EntityManager.merge(); essentially these are fresh instances just updated in DB.
In this case, calling DataManager.commit() should save the FileDescriptor instance in the database.The saved instance returned by this method can be set to an attribute of an entity related to this file. Here, FileDescriptor is simply stored in the database. The file will be available through the Administration > External Files screen.
You can read more about the file upload process using the FileUploadField in the documentation.
solved. Thanks a lot. However I don’t understand why I needo to commit changes. IN this sense commit means writing the filedescriptor in the file table, so I presume the stream is opened provided the information from that table.
Additionally I presume the datamanager.commit(), indeed commits a totally different transaction than the one managing the host standardeditor use case… otherwhise It would trigger errors in the host transaction.