diff --git a/cubicweb_rodolf/hooks.py b/cubicweb_rodolf/hooks.py
index 6e2beb8aabf131c145fb6941f8e4d78f2f279259_Y3ViaWN3ZWJfcm9kb2xmL2hvb2tzLnB5..6a3df8d582f34b8a47aba1d7f9448135db0d73a2_Y3ViaWN3ZWJfcm9kb2xmL2hvb2tzLnB5 100644
--- a/cubicweb_rodolf/hooks.py
+++ b/cubicweb_rodolf/hooks.py
@@ -20,7 +20,7 @@
 from datetime import datetime, timedelta
 import logging
 
-from cubicweb.server.hook import Hook
+from cubicweb.server.hook import Hook, match_rtype
 from cubicweb.predicates import is_instance
 
 from cubicweb_s3storage.storages import S3Storage
@@ -24,5 +24,6 @@
 from cubicweb.predicates import is_instance
 
 from cubicweb_s3storage.storages import S3Storage
+from rdflib import Graph
 
 from cubicweb_rodolf.import_data import import_data, launch_import_procedure
@@ -27,5 +28,6 @@
 
 from cubicweb_rodolf.import_data import import_data, launch_import_procedure
+from cubicweb_rodolf.process_helpers import upload_graph_to_virtuoso_endpoint
 
 
 RODOLF_IMPORT_DELTA = timedelta(
@@ -92,3 +94,24 @@
             import_data, import_process_eid=self.entity.eid
         )
         self._cw.commit()
+
+
+class UploadOntologyHook(Hook):
+    __regid__ = "rodolf.upload-ontology-hook"
+    __select__ = Hook.__select__ & match_rtype("ontology_file")
+    events = ("after_add_relation",)
+
+    def __call__(self):
+        ontology_graph = Graph()
+        file = self._cw.entity_from_eid(self.eidto)
+        procedure = self._cw.entity_from_eid(self.eidfrom)
+        ontology_graph.parse(
+            data=file.data.read(),
+            format=file.data_format,
+        )
+        upload_graph_to_virtuoso_endpoint(
+            procedure,
+            ontology_graph,
+            f"urn:rodolf:{procedure.eid}:ontology",
+            file.download_file_name(),
+        )
diff --git a/cubicweb_rodolf/process_helpers.py b/cubicweb_rodolf/process_helpers.py
index 6e2beb8aabf131c145fb6941f8e4d78f2f279259_Y3ViaWN3ZWJfcm9kb2xmL3Byb2Nlc3NfaGVscGVycy5weQ==..6a3df8d582f34b8a47aba1d7f9448135db0d73a2_Y3ViaWN3ZWJfcm9kb2xmL3Byb2Nlc3NfaGVscGVycy5weQ== 100644
--- a/cubicweb_rodolf/process_helpers.py
+++ b/cubicweb_rodolf/process_helpers.py
@@ -44,7 +44,6 @@
     graph: Graph,
     named_graph: str,
     filename: str,
-    log: logging.Logger,
 ) -> None:
     delete_graph(
         import_procedure.virtuoso_credentials,
diff --git a/frontend/src/api/cubicweb.ts b/frontend/src/api/cubicweb.ts
index 6e2beb8aabf131c145fb6941f8e4d78f2f279259_ZnJvbnRlbmQvc3JjL2FwaS9jdWJpY3dlYi50cw==..6a3df8d582f34b8a47aba1d7f9448135db0d73a2_ZnJvbnRlbmQvc3JjL2FwaS9jdWJpY3dlYi50cw== 100644
--- a/frontend/src/api/cubicweb.ts
+++ b/frontend/src/api/cubicweb.ts
@@ -63,7 +63,7 @@
         ref: "ontology_file",
       },
       data_format: file.type,
-      data_name: "ontologie.owl",
+      data_name: file.name,
     });
     transaction.push(setOntologyRql, {
       eid,
diff --git a/frontend/src/components/FileField.tsx b/frontend/src/components/FileField.tsx
index 6e2beb8aabf131c145fb6941f8e4d78f2f279259_ZnJvbnRlbmQvc3JjL2NvbXBvbmVudHMvRmlsZUZpZWxkLnRzeA==..6a3df8d582f34b8a47aba1d7f9448135db0d73a2_ZnJvbnRlbmQvc3JjL2NvbXBvbmVudHMvRmlsZUZpZWxkLnRzeA== 100644
--- a/frontend/src/components/FileField.tsx
+++ b/frontend/src/components/FileField.tsx
@@ -22,7 +22,7 @@
   const ref = useRef<HTMLInputElement>(null);
 
   const onPressOpen = async () => {
-    let fileToOpen = value?.data;
+    let fileToOpen = value?.data as Blob;
     // The file is available on the server, fetch it
     if (!fileToOpen && value?.downloadUrl) {
       fileToOpen = await downloadFile(value.downloadUrl);
diff --git a/frontend/src/types.ts b/frontend/src/types.ts
index 6e2beb8aabf131c145fb6941f8e4d78f2f279259_ZnJvbnRlbmQvc3JjL3R5cGVzLnRz..6a3df8d582f34b8a47aba1d7f9448135db0d73a2_ZnJvbnRlbmQvc3JjL3R5cGVzLnRz 100644
--- a/frontend/src/types.ts
+++ b/frontend/src/types.ts
@@ -1,6 +1,7 @@
 export type CWFile = {
   downloadUrl?: string;
-  data?: Blob;
+  data?: File;
+  updateKey?: number;
 };
 
 export type Project = {
diff --git a/test/test_rodolf.py b/test/test_rodolf.py
index 6e2beb8aabf131c145fb6941f8e4d78f2f279259_dGVzdC90ZXN0X3JvZG9sZi5weQ==..6a3df8d582f34b8a47aba1d7f9448135db0d73a2_dGVzdC90ZXN0X3JvZG9sZi5weQ== 100644
--- a/test/test_rodolf.py
+++ b/test/test_rodolf.py
@@ -53,5 +53,6 @@
         """
         return work(cnx, burst=True, worker_class=rq.worker.SimpleWorker)
 
-    def setUp(self):
+    @requests_mock.mock()
+    def setUp(self, mock):
         super(ImportDataTC, self).setUp()
@@ -57,4 +58,11 @@
         super(ImportDataTC, self).setUp()
+
+        # mock all Virtuoso query (delete and update graph)
+        mock.register_uri(
+            requests_mock.ANY,
+            "/sparql-graph-crud-auth?",
+        )
+
         self.fakeredis = fakeredis.FakeStrictRedis()
         with self.admin_access.cnx() as cnx:
             dataservice = cnx.create_entity(