diff --git a/fda-identifier-service/pom.xml b/fda-identifier-service/pom.xml
index afd2774486cbe822f7baecebd3dee575913310de..afbe31fee99b3a94a5772b97f06a3d89b433984d 100644
--- a/fda-identifier-service/pom.xml
+++ b/fda-identifier-service/pom.xml
@@ -57,6 +57,10 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-security</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-thymeleaf</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.springframework.security</groupId>
             <artifactId>spring-security-test</artifactId>
@@ -182,6 +186,7 @@
                 <filtering>true</filtering>
                 <includes>
                     <include>**/application*.yml</include>
+                    <include>**/templates/*.xml</include>
                 </includes>
             </resource>
         </resources>
diff --git a/fda-identifier-service/rest-service/src/main/java/at/tuwien/endpoints/IdentifierEndpoint.java b/fda-identifier-service/rest-service/src/main/java/at/tuwien/endpoints/IdentifierEndpoint.java
index 51d8cc4d5a993ad33fefddac1d5907c2298e7906..b4e9f30e7d07c3f647af8380e4a2a718016c9f81 100644
--- a/fda-identifier-service/rest-service/src/main/java/at/tuwien/endpoints/IdentifierEndpoint.java
+++ b/fda-identifier-service/rest-service/src/main/java/at/tuwien/endpoints/IdentifierEndpoint.java
@@ -1,6 +1,5 @@
 package at.tuwien.endpoints;
 
-import at.tuwien.ExportResource;
 import at.tuwien.api.identifier.IdentifierCreateDto;
 import at.tuwien.api.identifier.IdentifierDto;
 import at.tuwien.api.identifier.IdentifierTypeDto;
@@ -13,8 +12,6 @@ import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.security.SecurityRequirement;
 import lombok.extern.log4j.Log4j2;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.io.InputStreamResource;
-import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -58,22 +55,6 @@ public class IdentifierEndpoint {
         return ResponseEntity.ok(dto);
     }
 
-    @GetMapping("/{id}")
-    @Deprecated
-    @Transactional(readOnly = true)
-    @Timed(value = "identifier.export", description = "Time needed to export an identifier")
-    @Operation(summary = "Export some identifier metadata")
-    public ResponseEntity<InputStreamResource> export(@NotNull @PathVariable("id") Long id)
-            throws IdentifierNotFoundException {
-        log.debug("endpoint export identifier, id={}", id);
-        final HttpHeaders headers = new HttpHeaders();
-        final ExportResource resource = identifierService.exportMetadata(id);
-        headers.add("Content-Disposition", "attachment; filename=\"" + resource.getFilename() + "\"");
-        return ResponseEntity.ok()
-                .headers(headers)
-                .body(resource.getResource());
-    }
-
     @PostMapping
     @Transactional
     @Timed(value = "identifier.create", description = "Time needed to create an identifier")
diff --git a/fda-identifier-service/rest-service/src/main/java/at/tuwien/endpoints/PersistenceEndpoint.java b/fda-identifier-service/rest-service/src/main/java/at/tuwien/endpoints/PersistenceEndpoint.java
index 6150c9313bb7d77a415346ea0d60a833526cf9ff..b761546b6680d66e1d02a307fee5ee7180317eaa 100644
--- a/fda-identifier-service/rest-service/src/main/java/at/tuwien/endpoints/PersistenceEndpoint.java
+++ b/fda-identifier-service/rest-service/src/main/java/at/tuwien/endpoints/PersistenceEndpoint.java
@@ -1,6 +1,6 @@
 package at.tuwien.endpoints;
 
-import at.tuwien.ExportResource;
+import at.tuwien.api.identifier.IdentifierDto;
 import at.tuwien.config.EndpointConfig;
 import at.tuwien.entities.identifier.Identifier;
 import at.tuwien.exception.IdentifierNotFoundException;
@@ -13,6 +13,7 @@ import io.micrometer.core.annotation.Timed;
 import io.swagger.v3.oas.annotations.Operation;
 import lombok.extern.log4j.Log4j2;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.InputStreamResource;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
@@ -45,30 +46,41 @@ public class PersistenceEndpoint {
     public ResponseEntity<?> find(@Valid @PathVariable("pid") Long pid,
                                   @RequestHeader(HttpHeaders.ACCEPT) String accept) throws IdentifierNotFoundException,
             QueryNotFoundException, RemoteUnavailableException {
-        log.debug("find identifier endpoint, pid={}, accept={}", pid, accept);
+        log.debug("endpoint find identifier, pid={}, accept={}", pid, accept);
         final Identifier identifier = identifierService.find(pid);
         log.info("Found persistent identifier with id {}", identifier.getId());
         log.trace("found persistent identifier {}", identifier);
         if (accept != null) {
             log.trace("accept header present: {}", accept);
-            if (accept.equals("application/json")) {
-                log.trace("accept header matches json");
-                return ResponseEntity.ok(identifierMapper.identifierToIdentifierDto(identifier));
-            } else if (accept.equals("text/csv")) {
-                log.trace("accept header matches csv");
-                return ResponseEntity.ok(identifierService.exportResource(pid));
-            } else if (accept.equals("text/xml")) {
-                final HttpHeaders headers = new HttpHeaders();
-                final ExportResource resource = identifierService.exportMetadata(pid);
-                headers.add("Content-Disposition", "attachment; filename=\"" + resource.getFilename() + "\"");
-                return ResponseEntity.ok()
-                        .headers(headers)
-                        .body(resource.getResource());
+            switch (accept) {
+                case "application/json":
+                    log.trace("accept header matches json");
+                    final IdentifierDto resource1 = identifierMapper.identifierToIdentifierDto(identifier);
+                    log.debug("find identifier resulted in identifier {}", resource1);
+                    return ResponseEntity.ok(resource1);
+                case "text/csv":
+                    log.trace("accept header matches csv");
+                    final InputStreamResource resource2;
+                    try {
+                        resource2 = identifierService.exportResource(pid);
+                        log.debug("find identifier resulted in resource {}", resource2);
+                        return ResponseEntity.ok(resource2);
+                    } catch (IdentifierRequestException e) {
+                        /* ignore */
+                    }
+                case "text/xml":
+                    log.trace("accept header matches xml");
+                    final InputStreamResource resource3 = identifierService.exportMetadata(pid);
+                    log.debug("find identifier resulted in resource {}", resource3);
+                    return ResponseEntity.ok(resource3);
             }
+        } else {
+            log.trace("no accept header present");
         }
-        log.trace("no accept header present, serving http redirect");
         final HttpHeaders headers = new HttpHeaders();
-        headers.add("Location", identifierMapper.identifierToLocationUrl(endpointConfig.getWebsiteUrl(), identifier));
+        final String url = identifierMapper.identifierToLocationUrl(endpointConfig.getWebsiteUrl(), identifier);
+        headers.add("Location", url);
+        log.debug("find identifier resulted in http redirect, headers={}, url={}", headers, url);
         return ResponseEntity.status(HttpStatus.MOVED_PERMANENTLY)
                 .headers(headers)
                 .build();
diff --git a/fda-identifier-service/rest-service/src/main/resources/templates/doi.xml b/fda-identifier-service/rest-service/src/main/resources/templates/doi.xml
new file mode 100644
index 0000000000000000000000000000000000000000..81c7fccc9bf1ce052835b787bc4fb06e810cc3b9
--- /dev/null
+++ b/fda-identifier-service/rest-service/src/main/resources/templates/doi.xml
@@ -0,0 +1,49 @@
+<resource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://datacite.org/schema/kernel-4"
+          xsi:schemaLocation="http://datacite.org/schema/kernel-4 https://schema.datacite.org/meta/kernel-4.4/metadata.xsd">
+    <identifier identifierType="PID">[[${doi}]]</identifier>
+    <creators th:if="${not #lists.isEmpty(creators)}">
+        <creator th:each="creator: ${creators}">
+            <creatorName nameType="Personal">
+                [[${creator.name}]]
+            </creatorName>
+            <nameIdentifier th:if="${creator.orcid != null}" schemeURI="https://orcid.org" nameIdentifierScheme="ORCID">
+                [[${creator.orcid}]]
+            </nameIdentifier>
+            <affiliation th:if="${creator.affiliation != null}">
+                [[${creator.affiliation}]]
+            </affiliation>
+        </creator>
+    </creators>
+    <titles>
+        <title xml:lang="en">
+            [[${title}]]
+        </title>
+    </titles>
+    <publisher xml:lang="en">
+        [[${publisher}]]
+    </publisher>
+    <publicationYear>
+        [[${publicationYear}]]
+    </publicationYear>
+    <dates>
+        <date dateType="Issued">
+            [[${created}]]
+        </date>
+        <date dateType="Available">
+            [[${created}]]
+        </date>
+    </dates>
+    <resourceType resourceTypeGeneral="Dataset">Dataset</resourceType>
+    <relatedIdentifiers th:if="${not #lists.isEmpty(relatedIdentifiers)}">
+        <relatedIdentifier th:each="relatedIdentifier: ${relatedIdentifiers}"
+                           th:attr="relatedIdentifierType=${relatedIdentifier.type},relationType=${relatedIdentifier.relation}">
+            [[${relatedIdentifier.value}]]
+        </relatedIdentifier>
+    </relatedIdentifiers>
+    <descriptions th:if="${description != null}">
+        <description descriptionType="Abstract">
+            [[${description}]]
+        </description>
+    </descriptions>
+    <version>1.0</version>
+</resource>
\ No newline at end of file
diff --git a/fda-identifier-service/rest-service/src/main/java/at/tuwien/config/EndpointConfig.java b/fda-identifier-service/services/src/main/java/at/tuwien/config/EndpointConfig.java
similarity index 100%
rename from fda-identifier-service/rest-service/src/main/java/at/tuwien/config/EndpointConfig.java
rename to fda-identifier-service/services/src/main/java/at/tuwien/config/EndpointConfig.java
diff --git a/fda-identifier-service/services/src/main/java/at/tuwien/config/TemplateConfig.java b/fda-identifier-service/services/src/main/java/at/tuwien/config/TemplateConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..c2d1721c0ceaadb4c2f211deb9805b16b5b71c70
--- /dev/null
+++ b/fda-identifier-service/services/src/main/java/at/tuwien/config/TemplateConfig.java
@@ -0,0 +1,30 @@
+package at.tuwien.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.thymeleaf.spring5.SpringTemplateEngine;
+import org.thymeleaf.templatemode.TemplateMode;
+import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
+
+import java.nio.charset.StandardCharsets;
+
+@Configuration
+public class TemplateConfig {
+
+    @Bean
+    public SpringTemplateEngine springTemplateEngine() {
+        final SpringTemplateEngine springTemplateEngine = new SpringTemplateEngine();
+        springTemplateEngine.addTemplateResolver(oaiTemplateResolver());
+        return springTemplateEngine;
+    }
+
+    private ClassLoaderTemplateResolver oaiTemplateResolver() {
+        final ClassLoaderTemplateResolver oaiTemplateResolver = new ClassLoaderTemplateResolver();
+        oaiTemplateResolver.setPrefix("/templates/");
+        oaiTemplateResolver.setSuffix(".xml");
+        oaiTemplateResolver.setTemplateMode(TemplateMode.TEXT);
+        oaiTemplateResolver.setCharacterEncoding(StandardCharsets.UTF_8.name());
+        oaiTemplateResolver.setCacheable(false);
+        return oaiTemplateResolver;
+    }
+}
diff --git a/fda-identifier-service/services/src/main/java/at/tuwien/service/IdentifierService.java b/fda-identifier-service/services/src/main/java/at/tuwien/service/IdentifierService.java
index 261b5b71af3c407ec631dae7638cc9baff110a3e..e68c67d7ea1655b388dea23482e159e9ac7cc029 100644
--- a/fda-identifier-service/services/src/main/java/at/tuwien/service/IdentifierService.java
+++ b/fda-identifier-service/services/src/main/java/at/tuwien/service/IdentifierService.java
@@ -72,7 +72,7 @@ public interface IdentifierService {
      * @return The export, if successful.
      * @throws IdentifierNotFoundException The identifier was not found in the metadata database or was deleted.
      */
-    ExportResource exportMetadata(Long id) throws IdentifierNotFoundException;
+    InputStreamResource exportMetadata(Long id) throws IdentifierNotFoundException;
 
     /**
      * Exports an identifier to XML
@@ -81,10 +81,10 @@ public interface IdentifierService {
      * @return The XML resource, if successful.
      * @throws IdentifierNotFoundException The identifier was not found in the metadata database or was deleted.
      * @throws QueryNotFoundException      The query was not found in the metadata database or was deleted.
-     * @throws RemoteUnavailableException
+     * @throws RemoteUnavailableException  The remote service is not available
      */
     InputStreamResource exportResource(Long identifierId)
-            throws IdentifierNotFoundException, QueryNotFoundException, RemoteUnavailableException;
+            throws IdentifierNotFoundException, QueryNotFoundException, RemoteUnavailableException, IdentifierRequestException;
 
     /**
      * Updated the metadata (only) on the identifier for a given id in the metadata database.
diff --git a/fda-identifier-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java b/fda-identifier-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java
index d2fba7a6fb7450db5fba58d9c1ec454b69b4a92a..8e5aee90bebda8a45f73c89033aa2693430dca18 100644
--- a/fda-identifier-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java
+++ b/fda-identifier-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java
@@ -1,12 +1,11 @@
 package at.tuwien.service.impl;
 
-import at.tuwien.ExportResource;
-import at.tuwien.api.database.query.ExportDto;
 import at.tuwien.api.database.query.QueryDto;
 import at.tuwien.api.identifier.IdentifierCreateDto;
 import at.tuwien.api.identifier.IdentifierDto;
 import at.tuwien.api.identifier.IdentifierTypeDto;
 import at.tuwien.api.identifier.VisibilityTypeDto;
+import at.tuwien.config.EndpointConfig;
 import at.tuwien.entities.database.Database;
 import at.tuwien.entities.identifier.*;
 import at.tuwien.entities.user.User;
@@ -20,14 +19,15 @@ import at.tuwien.service.DatabaseService;
 import at.tuwien.service.IdentifierService;
 import at.tuwien.service.UserService;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
 import org.springframework.core.io.InputStreamResource;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.thymeleaf.TemplateEngine;
+import org.thymeleaf.context.Context;
 
 import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.IOException;
+import java.nio.charset.Charset;
 import java.security.Principal;
 import java.util.List;
 import java.util.Optional;
@@ -39,18 +39,23 @@ public class IdentifierServiceImpl implements IdentifierService {
 
     private final UserService userService;
     private final DocumentMapper documentMapper;
+    private final EndpointConfig endpointConfig;
+    private final TemplateEngine templateEngine;
     private final DatabaseService databaseService;
     private final IdentifierMapper identifierMapper;
     private final QueryServiceGateway queryServiceGateway;
     private final IdentifierRepository identifierRepository;
     private final RelatedIdentifierRepository relatedIdentifierRepository;
 
-    public IdentifierServiceImpl(UserService userService, DocumentMapper documentMapper,
-                                 DatabaseService databaseService, IdentifierMapper identifierMapper,
-                                 QueryServiceGateway queryServiceGateway, IdentifierRepository identifierRepository,
+    public IdentifierServiceImpl(UserService userService, DocumentMapper documentMapper, EndpointConfig endpointConfig,
+                                 TemplateEngine templateEngine, DatabaseService databaseService,
+                                 IdentifierMapper identifierMapper, QueryServiceGateway queryServiceGateway,
+                                 IdentifierRepository identifierRepository,
                                  RelatedIdentifierRepository relatedIdentifierRepository) {
         this.userService = userService;
         this.documentMapper = documentMapper;
+        this.endpointConfig = endpointConfig;
+        this.templateEngine = templateEngine;
         this.databaseService = databaseService;
         this.identifierMapper = identifierMapper;
         this.queryServiceGateway = queryServiceGateway;
@@ -170,22 +175,30 @@ public class IdentifierServiceImpl implements IdentifierService {
 
     @Override
     @Transactional(readOnly = true)
-    public ExportResource exportMetadata(Long id) throws IdentifierNotFoundException {
+    public InputStreamResource exportMetadata(Long id) throws IdentifierNotFoundException {
         /* check */
         final Identifier identifier = find(id);
+        /* context */
+        final Context context = new Context();
+        context.setVariable("doi", endpointConfig.getWebsiteUrl() + "/pid/" + identifier.getId());
+        context.setVariable("creators", identifier.getCreators());
+        context.setVariable("title", identifier.getTitle());
+        context.setVariable("publisher", identifier.getPublisher());
+        context.setVariable("publicationYear", identifier.getPublicationYear());
+        context.setVariable("created", documentMapper.instantToDate(identifier.getCreated()));
+        context.setVariable("relatedIdentifiers", identifier.getRelated());
+        context.setVariable("description", identifier.getDescription());
         /* map */
-        final InputStreamResource resource = documentMapper.identifierToInputStreamResource(identifier);
+        final String body = templateEngine.process("doi.xml", context);
+        final InputStreamResource resource = new InputStreamResource(IOUtils.toInputStream(body, Charset.defaultCharset()));
         log.debug("mapped file stream {}", resource.getDescription());
-        return ExportResource.builder()
-                .filename("metadata.xml")
-                .resource(resource)
-                .build();
+        return resource;
     }
 
     @Override
     @Transactional(readOnly = true)
-    public InputStreamResource exportResource(Long identifierId)
-            throws IdentifierNotFoundException, QueryNotFoundException, RemoteUnavailableException {
+    public InputStreamResource exportResource(Long identifierId) throws IdentifierNotFoundException,
+            QueryNotFoundException, RemoteUnavailableException, IdentifierRequestException {
         /* check */
         final Identifier identifier = find(identifierId);
         if (identifier.getType().equals(IdentifierType.DATABASE)) {
@@ -194,11 +207,20 @@ public class IdentifierServiceImpl implements IdentifierService {
             throw new IdentifierNotFoundException("Failed to find identifier");
         }
         /* export */
-        final byte[] file = queryServiceGateway.export(identifier.getContainerId(),
-                identifier.getDatabaseId(), identifier.getQueryId());
-        final InputStreamResource resource = new InputStreamResource(new ByteArrayInputStream(file));
-        log.trace("found resource {}", resource);
-        return resource;
+        if (identifier.getType().equals(IdentifierType.SUBSET)) {
+            /* subset */
+            final byte[] file = queryServiceGateway.export(identifier.getContainerId(),
+                    identifier.getDatabaseId(), identifier.getQueryId());
+            final InputStreamResource resource = new InputStreamResource(new ByteArrayInputStream(file));
+            log.trace("found resource {}", resource);
+            return resource;
+        } else if (identifier.getType().equals(IdentifierType.DATABASE)) {
+            /* database, we cannot export this to csv */
+            log.warn("Failed to export database to csv, fallback to default http redirect");
+            throw new IdentifierRequestException("Failed to export database to csv");
+        }
+        log.warn("Failed to export database, fallback to default http redirect");
+        throw new IdentifierRequestException("Failed to export database");
     }
 
     @Override
diff --git a/fda-metadata-db/api/src/main/java/at/tuwien/api/identifier/IdentifierBriefDto.java b/fda-metadata-db/api/src/main/java/at/tuwien/api/identifier/IdentifierBriefDto.java
index 4a7ac95ce07e4608489cee3cd09615bc1399db1c..c60e1e75076c6169392405c9b31216db2467eeac 100644
--- a/fda-metadata-db/api/src/main/java/at/tuwien/api/identifier/IdentifierBriefDto.java
+++ b/fda-metadata-db/api/src/main/java/at/tuwien/api/identifier/IdentifierBriefDto.java
@@ -1,6 +1,7 @@
 package at.tuwien.api.identifier;
 
 import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Builder;
@@ -41,9 +42,11 @@ public class IdentifierBriefDto {
     @NotNull
     private IdentifierTypeDto type;
 
+    @JsonIgnore
     @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "UTC")
     private Instant created;
 
+    @JsonIgnore
     @JsonProperty("last_modified")
     @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "UTC")
     private Instant lastModified;
diff --git a/fda-metadata-db/api/src/main/java/at/tuwien/api/user/UserBriefDto.java b/fda-metadata-db/api/src/main/java/at/tuwien/api/user/UserBriefDto.java
index 8bd0bab047a7cde4923c4cdbfe1f4a6e67df638a..fb9bd450a10e242859d0a7807cd79de9137a9e82 100644
--- a/fda-metadata-db/api/src/main/java/at/tuwien/api/user/UserBriefDto.java
+++ b/fda-metadata-db/api/src/main/java/at/tuwien/api/user/UserBriefDto.java
@@ -1,5 +1,6 @@
 package at.tuwien.api.user;
 
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -22,10 +23,12 @@ public class UserBriefDto {
     @Schema(example = "user", description = "Only contains lowercase characters")
     private String username;
 
+    @JsonIgnore
     @JsonProperty("titles_before")
     @Schema(example = "Prof.")
     private String titlesBefore;
 
+    @JsonIgnore
     @JsonProperty("titles_after")
     private String titlesAfter;
 
@@ -41,12 +44,12 @@ public class UserBriefDto {
     @Schema(example = "0000-0002-1825-0097")
     private String orcid;
 
-    @NotNull
+    @JsonIgnore
     @JsonProperty("theme_dark")
     @Schema(example = "true")
     private Boolean themeDark;
 
-    @NotNull
+    @JsonIgnore
     @JsonProperty("email_verified")
     @Schema(example = "true")
     private Boolean emailVerified;
diff --git a/fda-metadata-db/entities/src/main/java/at/tuwien/entities/identifier/RelatedType.java b/fda-metadata-db/entities/src/main/java/at/tuwien/entities/identifier/RelatedType.java
index 9e3174ed9ceae60377cf727663af07366908d7e6..34f98ef59116e35115a8324262b417b85862d9fc 100644
--- a/fda-metadata-db/entities/src/main/java/at/tuwien/entities/identifier/RelatedType.java
+++ b/fda-metadata-db/entities/src/main/java/at/tuwien/entities/identifier/RelatedType.java
@@ -1,22 +1,51 @@
 package at.tuwien.entities.identifier;
 
 public enum RelatedType {
-    DOI,
-    URL,
-    URN,
-    ARK,
-    ARXIV,
-    BIBCODE,
-    EAN13,
-    EISSN,
-    HANDLE,
-    IGSN,
-    ISBN,
-    ISTC,
-    LISSN,
-    LSID,
-    PMID,
-    PURL,
-    UPC,
-    W3ID;
+
+    DOI("DOI"),
+
+    URL("URL"),
+
+    URN("URN"),
+
+    ARK("ARK"),
+
+    ARXIV("arXiv"),
+
+    BIBCODE("bibcode"),
+
+    EAN13("EAN13"),
+
+    EISSN("EISSN"),
+
+    HANDLE("Handle"),
+
+    IGSN("IGSN"),
+
+    ISBN("ISBN"),
+
+    ISTC("ISTC"),
+
+    LISSN("LISSN"),
+
+    LSID("LSID"),
+
+    PMID("PMID"),
+
+    PURL("PURL"),
+
+    UPC("UPC"),
+
+    W3ID("w3id");
+
+    private String name;
+
+    RelatedType(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public String toString() {
+        return this.name;
+    }
 }
diff --git a/fda-metadata-db/entities/src/main/java/at/tuwien/entities/identifier/RelationType.java b/fda-metadata-db/entities/src/main/java/at/tuwien/entities/identifier/RelationType.java
index 5ba9f7726ef66b09523b7a3f3b4bbda956f63ecc..65fc23fddbdbe3dca3dedf0669ad4bdb9a2feb7e 100644
--- a/fda-metadata-db/entities/src/main/java/at/tuwien/entities/identifier/RelationType.java
+++ b/fda-metadata-db/entities/src/main/java/at/tuwien/entities/identifier/RelationType.java
@@ -1,38 +1,83 @@
 package at.tuwien.entities.identifier;
 
 public enum RelationType {
-    IS_CITED_BY,
-    CITES,
-    IS_SUPPLEMENT_TO,
-    IS_SUPPLEMENTED_BY,
-    IS_CONTINUED_BY,
-    CONTINUES,
-    IS_DESCRIBED_BY,
-    DESCRIBES,
-    HAS_METADATA,
-    IS_METADATA_FOR,
-    HAS_VERSION,
-    IS_VERSION_OF,
-    IS_NEW_VERSION_OF,
-    IS_PREVIOUS_VERSION_OF,
-    IS_PART_OF,
-    HAS_PART,
-    IS_PUBLISHED_IN,
-    IS_REFERENCED_BY,
-    REFERENCES,
-    IS_DOCUMENTED_BY,
-    DOCUMENTS,
-    IS_COMPILED_BY,
-    COMPILES,
-    IS_VARIANT_FORM_OF,
-    IS_ORIGINAL_FORM_OF,
-    IS_IDENTICAL_TO,
-    IS_REVIEWED_BY,
-    REVIEWS,
-    IS_DERIVED_FROM,
-    IS_SOURCE_OF,
-    IS_REQUIRED_BY,
-    REQUIRES,
-    IS_OBSOLETED_BY,
-    OBSOLETES,
+
+    IS_CITED_BY("IsCitedBy"),
+
+    CITES("Cites"),
+
+    IS_SUPPLEMENT_TO("IsSupplementTo"),
+
+    IS_SUPPLEMENTED_BY("IsSupplementedBy"),
+
+    IS_CONTINUED_BY("IsContinuedBy"),
+
+    CONTINUES("Continues"),
+
+    IS_DESCRIBED_BY("IsDescribedBy"),
+
+    DESCRIBES("Describes"),
+
+    HAS_METADATA("HasMetadata"),
+
+    IS_METADATA_FOR("IsMetadataFor"),
+
+    HAS_VERSION("HasVersion"),
+
+    IS_VERSION_OF("IsVersionOf"),
+
+    IS_NEW_VERSION_OF("IsNewVersionOf"),
+
+    IS_PREVIOUS_VERSION_OF("IsPreviousVersionOf"),
+
+    IS_PART_OF("IsPartOf"),
+
+    HAS_PART("HasPart"),
+
+    IS_PUBLISHED_IN("IsPublishedIn"),
+
+    IS_REFERENCED_BY("IsReferencedBy"),
+
+    REFERENCES("References"),
+
+    IS_DOCUMENTED_BY("IsDocumentedBy"),
+
+    DOCUMENTS("Documents"),
+
+    IS_COMPILED_BY("IsCompiledBy"),
+
+    COMPILES("Compiles"),
+
+    IS_VARIANT_FORM_OF("IsVariantFormOf"),
+
+    IS_ORIGINAL_FORM_OF("IsOriginalFormOf"),
+
+    IS_IDENTICAL_TO("IsIdenticalTo"),
+
+    IS_REVIEWED_BY("IsReviewedBy"),
+
+    REVIEWS("Reviews"),
+
+    IS_DERIVED_FROM("IsDerivedFrom"),
+
+    IS_SOURCE_OF("IsSourceOf"),
+
+    IS_REQUIRED_BY("IsRequiredBy"),
+
+    REQUIRES("Requires"),
+
+    IS_OBSOLETED_BY("IsObsoletedBy"),
+
+    OBSOLETES("Obsoletes");
+
+    private String name;
+
+    RelationType(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public String toString() {
+        return this.name;
+    }
 }
diff --git a/fda-query-service/services/src/main/java/at/tuwien/mapper/QueryMapper.java b/fda-query-service/services/src/main/java/at/tuwien/mapper/QueryMapper.java
index 87ba422bb1758f065cfaa3721a3dcf8de2094fa1..71b11475f3e852ba7102224c3d65aed0a7c294e3 100644
--- a/fda-query-service/services/src/main/java/at/tuwien/mapper/QueryMapper.java
+++ b/fda-query-service/services/src/main/java/at/tuwien/mapper/QueryMapper.java
@@ -318,9 +318,9 @@ public interface QueryMapper {
         table.getColumns()
                 .forEach(column -> {
                     statement.append(idx[0] != 0 ? "," : "")
-                            .append("`")
+                            .append("'")
                             .append(column.getInternalName())
-                            .append("`");
+                            .append("'");
                     idx[0]++;
                 });
         statement.append(" UNION ALL SELECT ");
@@ -333,7 +333,7 @@ public interface QueryMapper {
                             .append("`");
                     jdx[0]++;
                 });
-        statement.append("FROM `")
+        statement.append(" FROM `")
                 .append(table.getInternalName())
                 .append("`");
         if (timestamp != null) {
diff --git a/fda-ui/components/dialogs/PersistQuery.vue b/fda-ui/components/dialogs/Persist.vue
similarity index 88%
rename from fda-ui/components/dialogs/PersistQuery.vue
rename to fda-ui/components/dialogs/Persist.vue
index 7ef730fcde71c39c566ff4cbe5d9e1378ff88eba..bcc0e3ec393bca55d586369b83a8e46da87aac1c 100644
--- a/fda-ui/components/dialogs/PersistQuery.vue
+++ b/fda-ui/components/dialogs/Persist.vue
@@ -2,11 +2,10 @@
   <div>
     <v-card>
       <v-progress-linear v-if="loading" :color="loadingColor" :indeterminate="!error" />
-      <v-card-title>
-        Persist Subset and Result
-      </v-card-title>
+      <v-card-title v-text="`Persist ${title}`" />
       <v-card-text>
         <v-alert
+          v-if="is_subset"
           border="left"
           color="info">
           Choose an expressive subset title and describe what it produces.
@@ -18,7 +17,8 @@
                 id="title"
                 v-model="identifier.title"
                 name="title"
-                label="Subset Title *"
+                :label="`${prefix} title *`"
+                :disabled="is_database"
                 :rules="[v => !!v || $t('Required')]"
                 required />
               <v-textarea
@@ -26,7 +26,7 @@
                 v-model="identifier.description"
                 name="description"
                 rows="2"
-                label="Subset Description" />
+                :label="`${prefix} description *`" />
             </v-col>
           </v-row>
           <v-row dense>
@@ -35,7 +35,7 @@
                 id="publisher"
                 v-model="identifier.publisher"
                 name="publisher"
-                label="Subset Publisher *"
+                :label="`${prefix} publisher *`"
                 :rules="[v => !!v || $t('Required')]"
                 required />
             </v-col>
@@ -46,21 +46,21 @@
                 id="publication-day"
                 v-model.number="identifier.publication_day"
                 type="number"
-                label="Publication Day" />
+                label="Publication day" />
             </v-col>
             <v-col cols="2">
               <v-text-field
                 id="publication-month"
                 v-model.number="identifier.publication_month"
                 type="number"
-                label="Publication Month" />
+                label="Publication month" />
             </v-col>
             <v-col cols="3">
               <v-text-field
                 id="publication-year"
                 v-model.number="identifier.publication_year"
                 type="number"
-                label="Publication Year *"
+                label="Publication year *"
                 :rules="[v => !!v || $t('Required')]"
                 required />
             </v-col>
@@ -74,7 +74,7 @@
                 item-value="value"
                 :disabled="database.is_public"
                 item-text="name"
-                label="Visibility *"
+                :label="`${prefix} visibility *`"
                 :rules="[v => !!v || $t('Required')]"
                 required />
             </v-col>
@@ -84,7 +84,7 @@
               <v-text-field
                 v-model="creator.name"
                 name="name"
-                label="Name *"
+                label="Lastname, Firstname *"
                 :rules="[v => !!v || $t('Required')]"
                 required />
             </v-col>
@@ -178,6 +178,12 @@
 <script>
 import { formatYearUTC, formatMonthUTC, formatDayUTC } from '@/utils'
 export default {
+  props: {
+    type: {
+      type: String,
+      default: 'subset'
+    }
+  },
   data () {
     return {
       formValid: false,
@@ -289,12 +295,35 @@ export default {
         return null
       }
       return { Authorization: `Bearer ${this.token}` }
+    },
+    is_subset () {
+      return this.type === 'subset'
+    },
+    is_database () {
+      return this.type === 'database'
+    },
+    title () {
+      if (this.is_subset) {
+        return 'subset'
+      } else if (this.is_database) {
+        return 'database'
+      }
+      return ''
+    },
+    prefix () {
+      if (this.is_subset) {
+        return 'Subset'
+      } else if (this.is_database) {
+        return 'Database'
+      }
+      return ''
     }
   },
   mounted () {
     this.loadUser()
       .then(() => this.addCreatorSelf())
     this.loadDatabase()
+      .then(() => this.prefill())
   },
   methods: {
     cancel () {
@@ -358,11 +387,11 @@ export default {
       } catch (err) {
         this.error = true
         this.loading = false
-        this.$toast.error('Failed to persist query')
+        this.$toast.error('Failed to persist')
         console.error('persist failed', err)
         return
       }
-      this.$toast.success('Query persisted.')
+      this.$toast.success(this.prefix + ' successfully persisted')
       this.$emit('close', { action: 'persisted' })
       this.loading = false
     },
@@ -383,6 +412,14 @@ export default {
         console.error('load user data failed', err)
       }
       this.loading = false
+    },
+    prefill () {
+      if (!this.is_database) {
+        return
+      }
+      this.identifier.title = this.database.name
+      this.identifier.type = 'database'
+      console.debug('pre-filled identifier', this.identifier)
     }
   }
 }
diff --git a/fda-ui/components/dialogs/PersistDatabase.vue b/fda-ui/components/dialogs/PersistDatabase.vue
deleted file mode 100644
index c5c82e13c85c335b35500b365af07dd3c693f2bf..0000000000000000000000000000000000000000
--- a/fda-ui/components/dialogs/PersistDatabase.vue
+++ /dev/null
@@ -1,508 +0,0 @@
-<template>
-  <div>
-    <v-form ref="form" v-model="valid" @submit.prevent="submit">
-      <v-card flat>
-        <v-progress-linear v-if="loading" :color="loadingColor" :indeterminate="!error" />
-        <v-card-title>
-          Persist Database
-        </v-card-title>
-        <v-card-text>
-          <v-alert
-            border="left"
-            color="info">
-            Choose an expressive database description for the information stored.
-          </v-alert>
-          <v-row dense>
-            <v-col>
-              <v-text-field
-                id="title"
-                v-model="identifier.title"
-                name="title"
-                label="Title *"
-                disabled
-                :rules="[v => !!v || $t('Required')]"
-                required />
-            </v-col>
-          </v-row>
-          <v-row dense>
-            <v-col>
-              <v-text-field
-                id="publisher"
-                v-model="identifier.publisher"
-                name="publisher"
-                label="Publisher *"
-                :rules="[v => !!v || $t('Required')]"
-                required />
-            </v-col>
-          </v-row>
-          <v-row dense>
-            <v-col>
-              <v-textarea
-                id="description"
-                v-model="identifier.description"
-                name="description"
-                rows="2"
-                label="Description" />
-            </v-col>
-          </v-row>
-          <v-row dense>
-            <v-col>
-              <v-select
-                id="language"
-                v-model="identifier.language"
-                name="language"
-                label="Language"
-                :items="languages"
-                clearable
-                item-value="value"
-                item-text="text" />
-            </v-col>
-          </v-row>
-          <v-row dense>
-            <v-col cols="4">
-              <v-text-field
-                id="publication-day"
-                v-model.number="identifier.publication_day"
-                name="publication-day"
-                label="Publication Day"
-                hint="e.g. 08"
-                type="number"
-                clearable
-                min="1"
-                max="31" />
-            </v-col>
-            <v-col cols="4">
-              <v-text-field
-                id="publication-month"
-                v-model.number="identifier.publication_month"
-                name="publication-month"
-                label="Publication Month"
-                hint="e.g. 12"
-                type="number"
-                clearable
-                min="1"
-                max="12" />
-            </v-col>
-            <v-col cols="4">
-              <v-text-field
-                id="publication-year"
-                v-model.number="identifier.publication_year"
-                name="publication-year"
-                label="Publication Year *"
-                hint="e.g. 2022"
-                type="number"
-                clearable
-                :rules="[v => !!v || $t('Required')]"
-                required />
-            </v-col>
-          </v-row>
-          <v-row dense>
-            <v-col>
-              <v-select
-                id="license"
-                v-model="identifier.license"
-                name="license"
-                label="License"
-                :items="licenses"
-                clearable
-                item-value="identifier"
-                item-text="identifier"
-                return-object />
-            </v-col>
-          </v-row>
-          <v-row dense>
-            <v-col>
-              <v-select
-                v-if="false"
-                id="contact"
-                v-model="identifier.contact_person"
-                name="contact"
-                label="Contact"
-                :items="users"
-                clearable
-                item-value="username"
-                :item-text="item => `${printUser(item)}`" />
-            </v-col>
-          </v-row>
-        </v-card-text>
-        <v-card-actions>
-          <v-spacer />
-          <v-btn
-            class="mb-2"
-            @click="cancel">
-            Close
-          </v-btn>
-          <v-btn
-            id="database"
-            class="mb-2 mr-2"
-            :disabled="!valid || loading"
-            color="primary"
-            type="submit"
-            @click="persist">
-            Persist
-          </v-btn>
-        </v-card-actions>
-      </v-card>
-    </v-form>
-  </div>
-</template>
-
-<script>
-import { formatDayUTC, formatMonthUTC, formatUser, formatYearUTC } from '@/utils'
-export default {
-  props: {
-    database: {
-      type: Object,
-      default () {
-        return {}
-      }
-    }
-  },
-  data () {
-    return {
-      valid: false,
-      loading: false,
-      error: false,
-      menu: false,
-      users: [],
-      identifier: {
-        cid: parseInt(this.$route.params.container_id),
-        dbid: parseInt(this.$route.params.database_id),
-        title: null,
-        publisher: 'TU Wien',
-        description: null,
-        publication_year: formatYearUTC(Date.now()),
-        publication_month: formatMonthUTC(Date.now()),
-        publication_day: formatDayUTC(Date.now()),
-        type: 'database',
-        visibility: 'everyone',
-        doi: null,
-        creators: [],
-        related_identifiers: []
-      },
-      relatedTypes: [
-        { value: 'DOI' },
-        { value: 'URL' },
-        { value: 'URN' },
-        { value: 'ARK' },
-        { value: 'arXiv' },
-        { value: 'bibcode' },
-        { value: 'EAN13' },
-        { value: 'EISSN' },
-        { value: 'Handle' },
-        { value: 'IGSN' },
-        { value: 'ISBN' },
-        { value: 'ISTC' },
-        { value: 'LISSN' },
-        { value: 'LSID' },
-        { value: 'PMID' },
-        { value: 'PURL' },
-        { value: 'UPC' },
-        { value: 'w3id' }
-      ],
-      relationTypes: [
-        { value: 'IsCitedBy' },
-        { value: 'Cites' },
-        { value: 'IsSupplementTo' },
-        { value: 'IsSupplementedBy' },
-        { value: 'IsContinuedBy' },
-        { value: 'Continues' },
-        { value: 'IsDescribedBy' },
-        { value: 'Describes' },
-        { value: 'HasMetadata' },
-        { value: 'IsMetadataFor' },
-        { value: 'HasVersion' },
-        { value: 'IsVersionOf' },
-        { value: 'IsNewVersionOf' },
-        { value: 'IsPreviousVersionOf' },
-        { value: 'IsPartOf' },
-        { value: 'HasPart' },
-        { value: 'IsPublishedIn' },
-        { value: 'IsReferencedBy' },
-        { value: 'References' },
-        { value: 'IsDocumentedBy' },
-        { value: 'Documents' },
-        { value: 'IsCompiledBy' },
-        { value: 'Compiles' },
-        { value: 'IsVariantFormOf' },
-        { value: 'IsOriginalFormOf' },
-        { value: 'IsIdenticalTo' },
-        { value: 'IsReviewedBy' },
-        { value: 'Reviews' },
-        { value: 'IsDerivedFrom' },
-        { value: 'IsSourceOf' },
-        { value: 'IsRequiredBy' },
-        { value: 'Requires' },
-        { value: 'IsObsoletedBy' },
-        { value: 'Obsoletes' }
-      ],
-      licenses: [],
-      languages: [
-        { text: 'aa', value: 'aa' },
-        { text: 'ab', value: 'ab' },
-        { text: 'ae', value: 'ae' },
-        { text: 'af', value: 'af' },
-        { text: 'ak', value: 'ak' },
-        { text: 'am', value: 'am' },
-        { text: 'an', value: 'an' },
-        { text: 'ar', value: 'ar' },
-        { text: 'as', value: 'as' },
-        { text: 'av', value: 'av' },
-        { text: 'ay', value: 'ay' },
-        { text: 'az', value: 'az' },
-        { text: 'ba', value: 'ba' },
-        { text: 'be', value: 'be' },
-        { text: 'bg', value: 'bg' },
-        { text: 'bh', value: 'bh' },
-        { text: 'bi', value: 'bi' },
-        { text: 'bm', value: 'bm' },
-        { text: 'bn', value: 'bn' },
-        { text: 'bo', value: 'bo' },
-        { text: 'br', value: 'br' },
-        { text: 'bs', value: 'bs' },
-        { text: 'ca', value: 'ca' },
-        { text: 'ce', value: 'ce' },
-        { text: 'ch', value: 'ch' },
-        { text: 'co', value: 'co' },
-        { text: 'cr', value: 'cr' },
-        { text: 'cs', value: 'cs' },
-        { text: 'cu', value: 'cu' },
-        { text: 'cv', value: 'cv' },
-        { text: 'cy', value: 'cy' },
-        { text: 'da', value: 'da' },
-        { text: 'de', value: 'de' },
-        { text: 'dv', value: 'dv' },
-        { text: 'dz', value: 'dz' },
-        { text: 'ee', value: 'ee' },
-        { text: 'el', value: 'el' },
-        { text: 'en', value: 'en' },
-        { text: 'eo', value: 'eo' },
-        { text: 'es', value: 'es' },
-        { text: 'et', value: 'et' },
-        { text: 'eu', value: 'eu' },
-        { text: 'fa', value: 'fa' },
-        { text: 'ff', value: 'ff' },
-        { text: 'fi', value: 'fi' },
-        { text: 'fj', value: 'fj' },
-        { text: 'fo', value: 'fo' },
-        { text: 'fr', value: 'fr' },
-        { text: 'fy', value: 'fy' },
-        { text: 'ga', value: 'ga' },
-        { text: 'gd', value: 'gd' },
-        { text: 'gl', value: 'gl' },
-        { text: 'gn', value: 'gn' },
-        { text: 'gu', value: 'gu' },
-        { text: 'gv', value: 'gv' },
-        { text: 'ha', value: 'ha' },
-        { text: 'he', value: 'he' },
-        { text: 'hi', value: 'hi' },
-        { text: 'ho', value: 'ho' },
-        { text: 'hr', value: 'hr' },
-        { text: 'ht', value: 'ht' },
-        { text: 'hu', value: 'hu' },
-        { text: 'hy', value: 'hy' },
-        { text: 'hz', value: 'hz' },
-        { text: 'ia', value: 'ia' },
-        { text: 'id', value: 'id' },
-        { text: 'ie', value: 'ie' },
-        { text: 'ig', value: 'ig' },
-        { text: 'ii', value: 'ii' },
-        { text: 'ik', value: 'ik' },
-        { text: 'io', value: 'io' },
-        { text: 'is', value: 'is' },
-        { text: 'it', value: 'it' },
-        { text: 'iu', value: 'iu' },
-        { text: 'ja', value: 'ja' },
-        { text: 'jv', value: 'jv' },
-        { text: 'ka', value: 'ka' },
-        { text: 'kg', value: 'kg' },
-        { text: 'ki', value: 'ki' },
-        { text: 'kj', value: 'kj' },
-        { text: 'kk', value: 'kk' },
-        { text: 'kl', value: 'kl' },
-        { text: 'km', value: 'km' },
-        { text: 'kn', value: 'kn' },
-        { text: 'ko', value: 'ko' },
-        { text: 'kr', value: 'kr' },
-        { text: 'ks', value: 'ks' },
-        { text: 'ku', value: 'ku' },
-        { text: 'kv', value: 'kv' },
-        { text: 'kw', value: 'kw' },
-        { text: 'ky', value: 'ky' },
-        { text: 'la', value: 'la' },
-        { text: 'lb', value: 'lb' },
-        { text: 'lg', value: 'lg' },
-        { text: 'li', value: 'li' },
-        { text: 'ln', value: 'ln' },
-        { text: 'lo', value: 'lo' },
-        { text: 'lt', value: 'lt' },
-        { text: 'lu', value: 'lu' },
-        { text: 'lv', value: 'lv' },
-        { text: 'mg', value: 'mg' },
-        { text: 'mh', value: 'mh' },
-        { text: 'mi', value: 'mi' },
-        { text: 'mk', value: 'mk' },
-        { text: 'ml', value: 'ml' },
-        { text: 'mn', value: 'mn' },
-        { text: 'mr', value: 'mr' },
-        { text: 'ms', value: 'ms' },
-        { text: 'mt', value: 'mt' },
-        { text: 'my', value: 'my' },
-        { text: 'na', value: 'na' },
-        { text: 'nb', value: 'nb' },
-        { text: 'nd', value: 'nd' },
-        { text: 'ne', value: 'ne' },
-        { text: 'ng', value: 'ng' },
-        { text: 'nl', value: 'nl' },
-        { text: 'nn', value: 'nn' },
-        { text: 'no', value: 'no' },
-        { text: 'nr', value: 'nr' },
-        { text: 'nv', value: 'nv' },
-        { text: 'ny', value: 'ny' },
-        { text: 'oc', value: 'oc' },
-        { text: 'oj', value: 'oj' },
-        { text: 'om', value: 'om' },
-        { text: 'or', value: 'or' },
-        { text: 'os', value: 'os' },
-        { text: 'pa', value: 'pa' },
-        { text: 'pi', value: 'pi' },
-        { text: 'pl', value: 'pl' },
-        { text: 'ps', value: 'ps' },
-        { text: 'pt', value: 'pt' },
-        { text: 'qu', value: 'qu' },
-        { text: 'rm', value: 'rm' },
-        { text: 'rn', value: 'rn' },
-        { text: 'ro', value: 'ro' },
-        { text: 'ru', value: 'ru' },
-        { text: 'rw', value: 'rw' },
-        { text: 'sa', value: 'sa' },
-        { text: 'sc', value: 'sc' },
-        { text: 'sd', value: 'sd' },
-        { text: 'se', value: 'se' },
-        { text: 'sg', value: 'sg' },
-        { text: 'si', value: 'si' },
-        { text: 'sk', value: 'sk' },
-        { text: 'sl', value: 'sl' },
-        { text: 'sm', value: 'sm' },
-        { text: 'sn', value: 'sn' },
-        { text: 'so', value: 'so' },
-        { text: 'sq', value: 'sq' },
-        { text: 'sr', value: 'sr' },
-        { text: 'ss', value: 'ss' },
-        { text: 'st', value: 'st' },
-        { text: 'su', value: 'su' },
-        { text: 'sv', value: 'sv' },
-        { text: 'sw', value: 'sw' },
-        { text: 'ta', value: 'ta' },
-        { text: 'te', value: 'te' },
-        { text: 'tg', value: 'tg' },
-        { text: 'th', value: 'th' },
-        { text: 'ti', value: 'ti' },
-        { text: 'tk', value: 'tk' },
-        { text: 'tl', value: 'tl' },
-        { text: 'tn', value: 'tn' },
-        { text: 'to', value: 'to' },
-        { text: 'tr', value: 'tr' },
-        { text: 'ts', value: 'ts' },
-        { text: 'tt', value: 'tt' },
-        { text: 'tw', value: 'tw' },
-        { text: 'ty', value: 'ty' },
-        { text: 'ug', value: 'ug' },
-        { text: 'uk', value: 'uk' },
-        { text: 'ur', value: 'ur' },
-        { text: 'uz', value: 'uz' },
-        { text: 've', value: 've' },
-        { text: 'vi', value: 'vi' },
-        { text: 'vo', value: 'vo' },
-        { text: 'wa', value: 'wa' },
-        { text: 'wo', value: 'wo' },
-        { text: 'xh', value: 'xh' },
-        { text: 'yi', value: 'yi' },
-        { text: 'yo', value: 'yo' },
-        { text: 'za', value: 'za' },
-        { text: 'zh', value: 'zh' },
-        { text: 'zu', value: 'zu' }
-      ]
-    }
-  },
-  computed: {
-    loadingColor () {
-      return this.error ? 'red lighten-2' : 'primary'
-    },
-    token () {
-      return this.$store.state.token
-    },
-    config () {
-      if (this.token === null) {
-        return {}
-      }
-      return {
-        headers: { Authorization: `Bearer ${this.token}` }
-      }
-    }
-  },
-  mounted () {
-    this.loadLicenses()
-    this.loadUsers()
-    this.identifier.title = this.database.name
-    this.identifier.publication_year = parseInt(new Date().getFullYear())
-  },
-  methods: {
-    printUser (item) {
-      return formatUser(item)
-    },
-    submit () {
-      this.$refs.form.validate()
-    },
-    cancel () {
-      this.$emit('close-dialog', { success: false })
-    },
-    reset () {
-      this.menu = false
-    },
-    async loadLicenses () {
-      try {
-        this.loading = true
-        const res = await this.$axios.get(`/api/container/${this.$route.params.container_id}/database/license`)
-        this.licenses = res.data
-        console.debug('licenses', this.licenses)
-      } catch (err) {
-        this.error = true
-        this.$toast.error('Failed to fetch licenses')
-      }
-      this.loading = false
-    },
-    async loadUsers () {
-      try {
-        this.loading = true
-        const res = await this.$axios.get('/api/user')
-        this.users = res.data
-        console.debug('users', this.users)
-      } catch (err) {
-        this.error = true
-        this.$toast.error('Failed to fetch users')
-      }
-      this.loading = false
-    },
-    async persist () {
-      this.loading = true
-      try {
-        this.loading = true
-        const res = await this.$axios.post('/api/identifier', this.identifier, this.config)
-        console.debug('persist', res.data)
-        this.$toast.success('Database persisted.')
-        this.$emit('close-dialog', { action: 'persisted', success: true })
-      } catch (err) {
-        this.error = true
-        this.loading = false
-        this.$toast.error('Failed to persist database')
-        console.error('persist failed', err)
-        return
-      }
-      this.loading = false
-    }
-  }
-}
-</script>
-<style scoped>
-</style>
diff --git a/fda-ui/pages/container/_container_id/database/_database_id/info.vue b/fda-ui/pages/container/_container_id/database/_database_id/info.vue
index c5e15c0bbb0792102ea61eb16df999ccad2f8214..e6009507e31100af4d9f35fb64c9ae9e143f348d 100644
--- a/fda-ui/pages/container/_container_id/database/_database_id/info.vue
+++ b/fda-ui/pages/container/_container_id/database/_database_id/info.vue
@@ -24,6 +24,15 @@
                     <v-skeleton-loader v-if="loading" type="text" class="skeleton-small" />
                     <span v-if="!loading">{{ publisher }}</span>
                   </v-list-item-content>
+                  <v-list-item-title v-if="database.identifier.creators.length > 0" class="mt-2">
+                    Creators
+                  </v-list-item-title>
+                  <v-list-item-content>
+                    <span v-for="(person_or_org, i) in database.identifier.creators" :key="`c-${i}`" class="mt-1">
+                      <OrcidIcon v-if="person_or_org.orcid" :orcid="person_or_org.orcid" />
+                      {{ person_or_org.name }} <sup v-if="person_or_org.affiliation">{{ person_or_org.affiliation }}</sup>
+                    </span>
+                  </v-list-item-content>
                   <v-list-item-title v-if="language" class="mt-2">
                     Language
                   </v-list-item-title>
@@ -38,6 +47,33 @@
                     <v-skeleton-loader v-if="loading" type="text" class="skeleton-small" />
                     <span v-if="!loading" v-text="publication" />
                   </v-list-item-content>
+                  <v-list-item-title v-if="database.identifier.related.length > 0" class="mt-2">
+                    Related Identifiers
+                  </v-list-item-title>
+                  <v-list-item-content v-if="database.identifier.related.length > 0">
+                    <div v-for="(rel, i) in database.identifier.related" :key="`r-${i}`">
+                      <span v-if="rel.type === 'DOI'">
+                        {{ rel.type }}: <a :href="`https://doi.org/${rel.value}`" target="_blank">{{ rel.value }}</a>
+                        <span v-if="rel.relation">({{ rel.relation }})</span>
+                      </span>
+                      <span v-if="rel.type === 'URL'">
+                        {{ rel.type }}: <a :href="`${rel.value}`" target="_blank">{{ rel.value }}</a>
+                        <span v-if="rel.relation">({{ rel.relation }})</span>
+                      </span>
+                      <span v-if="rel.type === 'arXiv'">
+                        {{ rel.type }}: <a :href="`https://arxiv.org/abs/${rel.value}`" target="_blank">{{ rel.value }}</a>
+                        <span v-if="rel.relation">({{ rel.relation }})</span>
+                      </span>
+                      <span v-if="rel.type === 'EISSN'">
+                        {{ rel.type }}: <a :href="`https://portal.issn.org/resource/ISSN/${rel.value}`" target="_blank">{{ rel.value }}</a>
+                        <span v-if="rel.relation">({{ rel.relation }})</span>
+                      </span>
+                      <span v-if="rel.type !== 'DOI' && rel.type !== 'URL' && rel.type !== 'arXiv' && rel.type !== 'EISSN'">
+                        {{ rel.type }}: {{ rel.value }}
+                        <span v-if="rel.relation">({{ rel.relation }})</span>
+                      </span>
+                    </div>
+                  </v-list-item-content>
                   <v-list-item-title v-if="database.identifier.license" class="mt-2">
                     License
                   </v-list-item-title>
@@ -49,6 +85,16 @@
                 </v-list-item-content>
               </v-list-item>
             </v-list>
+            <v-card-actions>
+              <v-btn
+                v-if="hasIdentifier"
+                small
+                color="secondary"
+                :loading="metadataLoading"
+                @click.stop="download">
+                <v-icon left>mdi-code-tags</v-icon> Metadata .xml
+              </v-btn>
+            </v-card-actions>
           </v-card-text>
         </v-card>
         <v-divider v-if="hasIdentifier" />
@@ -146,7 +192,7 @@
                 v-model="editDbDialog"
                 persistent
                 max-width="860">
-                <PersistDatabase :database="database" @close-dialog="closeDialog" />
+                <Persist type="database" @close="closeDialog" />
               </v-dialog>
               <v-dialog
                 v-model="editVisibilityDialog"
@@ -179,8 +225,9 @@
 
 <script>
 import DBToolbar from '@/components/DBToolbar'
-import PersistDatabase from '@/components/dialogs/PersistDatabase'
+import Persist from '@/components/dialogs/Persist'
 import EditVisibility from '@/components/dialogs/EditVisibility'
+import OrcidIcon from '@/components/icons/OrcidIcon'
 import { formatTimestampUTCLabel, formatUser } from '@/utils'
 import { decodeJwt } from 'jose'
 
@@ -188,13 +235,15 @@ export default {
   components: {
     EditVisibility,
     DBToolbar,
-    PersistDatabase
+    Persist,
+    OrcidIcon
   },
   data () {
     return {
       loading: false,
       editDbDialog: false,
       editVisibilityDialog: false,
+      metadataLoading: false,
       user: {
         username: null
       },
@@ -338,12 +387,32 @@ export default {
       this.loading = false
     },
     closeDialog (event) {
-      if (event.success) {
+      if (event.action === 'persisted') {
         this.loadDatabase()
       }
       this.editDbDialog = false
       this.editVisibilityDialog = false
     },
+    async download () {
+      this.metadataLoading = true
+      try {
+        const config = this.config
+        config.headers.Accept = 'text/xml'
+        const res = await this.$axios.get(`/api/pid/${this.database.identifier.id}`, config)
+        console.debug('export identifier', res)
+        const url = window.URL.createObjectURL(new Blob([res.data]))
+        const link = document.createElement('a')
+        link.href = url
+        link.setAttribute('download', 'identifier.xml')
+        document.body.appendChild(link)
+        link.click()
+      } catch (err) {
+        console.error('Could not export identifier', err)
+        this.$toast.error('Could not export identifier')
+        this.error = true
+      }
+      this.metadataLoading = false
+    },
     loadUser () {
       if (!this.token) {
         return
diff --git a/fda-ui/pages/container/_container_id/database/_database_id/query/_query_id/index.vue b/fda-ui/pages/container/_container_id/database/_database_id/query/_query_id/index.vue
index fcfe0476215d16cc33d77c068f32cd06fb15a227..2ecde3b1de04b138ca29d7ec4a2ef9626d881598 100644
--- a/fda-ui/pages/container/_container_id/database/_database_id/query/_query_id/index.vue
+++ b/fda-ui/pages/container/_container_id/database/_database_id/query/_query_id/index.vue
@@ -18,7 +18,10 @@
         <v-btn v-if="token && query.is_persisted && !identifier.id && !loadingIdentifier && is_owner" class="mb-1 mr-2" color="primary" :disabled="error || erroneous || !executionUTC" @click.stop="openDialog()">
           <v-icon left>mdi-content-save-outline</v-icon> Get PID
         </v-btn>
-        <v-btn v-if="result_visibility" class="mb-1" :loading="downloadLoading" @click.stop="download('text/csv')">
+        <v-btn v-if="result_visibility && !identifier.id" class="mb-1" :loading="downloadLoading" @click.stop="downloadData">
+          <v-icon left>mdi-download</v-icon> Data .csv
+        </v-btn>
+        <v-btn v-if="result_visibility && identifier.id" class="mb-1" :loading="downloadLoading" @click.stop="download('text/csv')">
           <v-icon left>mdi-download</v-icon> Data .csv
         </v-btn>
         <v-btn
@@ -241,12 +244,12 @@
       v-model="persistQueryDialog"
       persistent
       max-width="860">
-      <PersistQuery @close="closeDialog" />
+      <Persist @close="closeDialog" />
     </v-dialog>
   </div>
 </template>
 <script>
-import PersistQuery from '@/components/dialogs/PersistQuery'
+import Persist from '@/components/dialogs/Persist'
 import OrcidIcon from '@/components/icons/OrcidIcon'
 import { formatTimestampUTCLabel, formatDateUTC } from '@/utils'
 import { decodeJwt } from 'jose'
@@ -254,7 +257,7 @@ import { decodeJwt } from 'jose'
 export default {
   name: 'QueryShow',
   components: {
-    PersistQuery,
+    Persist,
     OrcidIcon
   },
   data () {
@@ -449,7 +452,11 @@ export default {
       this.$refs.queryResults.reExecute(this.query.id)
     },
     async download (mime) {
-      this.downloadLoading = true
+      if (mime === 'text/csv') {
+        this.downloadLoading = true
+      } else if (mime === 'text/xml') {
+        this.metadataLoading = true
+      }
       try {
         const config = this.config
         config.headers.Accept = mime
@@ -471,6 +478,27 @@ export default {
         this.error = true
       }
       this.downloadLoading = false
+      this.metadataLoading = false
+    },
+    async downloadData () {
+      this.downloadLoading = true
+      try {
+        const config = this.config
+        config.headers.Accept = 'text/csv'
+        const res = await this.$axios.get(`/api/container/${this.$route.params.container_id}/database/${this.$route.params.database_id}/query/${this.$route.params.query_id}/export`, config)
+        console.debug('export query data', res)
+        const url = window.URL.createObjectURL(new Blob([res.data]))
+        const link = document.createElement('a')
+        link.href = url
+        link.setAttribute('download', 'subset.csv')
+        document.body.appendChild(link)
+        link.click()
+      } catch (err) {
+        console.error('Could not export query data', err)
+        this.$toast.error('Could not export query data')
+        this.error = true
+      }
+      this.downloadLoading = false
     },
     async loadQuery () {
       this.loadingQuery = true