HAPI FHIR migration and data loading

Moving clinical data from a legacy system or another FHIR server into HAPI FHIR is mostly mapping, validation and reconciliation work, and its cost follows the source data's quality and the number of resource types. This page covers what the work includes, what drives effort, and what you provide.

On this page

What a HAPI FHIR migration involves

Moving clinical data into a HAPI FHIR JPA server is a data engineering project, not a server installation. The server itself is the easy part: the JPA server starter can be deployed as a Docker image, with Spring Boot, as a WAR, or on Kubernetes. The work lies in moving records from a legacy clinical system, flat files, HL7 v2 feeds or another FHIR server into valid FHIR resources, with mapping, transaction loading, validation and reconciliation as the bulk of the effort.

Teams usually start this work when one of three things happens: they are retiring an EHR interface engine and need its message history available through FHIR, they are consolidating several FHIR servers into one, or they are building a new FHIR API over historical data that was never exposed that way. Each trigger changes the source inventory, the volume and how much history must be preserved, so confirm the source list and retention obligations before choosing a loading approach.

Most organizations can run the server in-house, but mapping clinical codes, reconciling patient identities across sources and writing transaction bundles that load cleanly at volume require people who know both HL7 v2 or the source schema and FHIR resource modeling. Ask whether your team has someone who has done bulk FHIR loads on the JPA server before. If not, a partner can scope the mapping and reconciliation work separately from the server build, which keeps the fixed-scope quote tied to clear deliverables.

What the work includes

The migration service covers the data work between a legacy source and a HAPI FHIR JPA server you already run. Each card below is a package that produces a concrete artifact you can review before the load.

Source inventory and data profiling

We inventory the source systems, tables, interfaces and code sets that hold clinical data, then profile field completeness, value distributions, duplicates and coded values. The output shows which data is loadable as-is, which needs cleansing, and which should stay out of scope. Ask for the profiling report before mapping starts, since it sets the real volume of exceptions.

Target FHIR version selection

We recommend a FHIR release from DSTU2, DSTU3, R4, R4B or R5, based on what the JPA server supports, your receiving applications, and the standard profiles your partners expect. The choice fixes the resource definitions every later mapping uses. Confirm the version against the HAPI FHIR release you plan to run, because version support differs between server releases.

Mapping specifications and profiles

We write field-level mapping specifications from source columns and codes to FHIR resources, elements, references and terminology bindings, and identify where a target profile needs constraints or extensions. Each rule records its source, transformation logic and the owner who approved it. Review unmapped source fields first, because those are where clinical meaning is most often lost.

Transform and load pipeline

We build the transform and load pipeline to post data as FHIR transaction Bundles, using conditional create, update and delete operations keyed on business identifiers. Conditional operations let a load be rerun without duplicating resources. Confirm batch sizes, error handling and ordering of dependent resources against your server's transaction limits before the first full run.

Validation against target profiles

Transformed resources are validated against the target FHIR version and the profiles you specify before they reach the server. Failures are grouped by rule and by source system so the mapping owner can fix root causes rather than individual records. Ask which validator version and which profile packages the validation run uses, so results can be reproduced later.

Reconciliation reports

We reconcile record counts, identifiers and selected field values between source and target, and report every difference with a documented reason or a fix. Reconciliation runs after each load and again after cutover. Agree in advance which fields and which tolerance levels count as a match, since that decision determines what the report can prove.

Handover deliverables

At handover you receive the mapping documents, load scripts, reconciliation evidence and a runbook that explains how to rerun a load, handle rejected bundles and roll back a batch. The runbook is written so your team can operate the loads without us. Confirm the handover format and acceptance criteria in the written scope before the work starts.

What drives cost and duration

This table lists the factors that move migration effort for a HAPI FHIR load, why each one matters, and how to keep it down, so you can compare them against the written scope a partner proposes.

DriverWhy it moves effortHow to keep it down
Source systemsEach legacy system has its own export format, extract method, access rules and data owner, so every added source adds discovery, extraction and reconciliation work.Confirm the authoritative source for each data domain and exclude systems that only hold copies or retired data.
Resource types and profiles in scopeEach FHIR resource type and each target profile needs its own mapping, example data and validation rules, and effort grows with every profile constraint.Start with the resource types the first clinical workflow needs and defer others to a later load wave.
Local codes and terminology mappingLocal lab, diagnosis and medication codes must be mapped to standard code systems such as LOINC, SNOMED CT or RxNorm, and inconsistent local coding multiplies review cycles with clinical owners.Measure the share of distinct local codes before scoping, retire unused codes, and agree on a governed mapping table with clinical sign-off.
Data quality and consistencyMissing required fields, free-text dates, mixed units and inconsistent formats cause rejected transactions and manual correction rounds.Profile source data early, set rejection thresholds per domain, and fix recurring defects at the source where possible.
Historical record volumeLarger volumes lengthen trial loads, increase transaction runtimes and database sizing work, and extend reconciliation counts.Decide with clinical and records owners how much history is required, and load older data in a separate, later batch.
Duplicate patients and identity matchingDuplicate person records must be matched or merged before resource linking, and match rules need tuning and manual review of uncertain pairs.Agree on matching criteria and a review workflow before mapping starts, and decide whether HAPI FHIR MDM will be used or an external tool.
Attachments and documentsScanned documents and embedded binaries need separate storage handling, size limits, metadata mapping and access controls.Decide which documents migrate, keep large archives in existing storage with references, and set a size and format policy.
Target FHIR version and profile strictnessStricter conformance to a chosen version and implementation guide raises the number of failed resources and the amount of mapping logic needed.Choose the FHIR release and profiles that the receiving systems actually require, and validate against them early in a sandbox.
Environments and cutover rehearsalsEach environment needs its own load, verification and configuration, and every full rehearsal repeats the load, reconciliation and sign-off steps.Limit environments to those the plan needs and set a fixed number of rehearsals with exit criteria for each.
Compliance evidence requirementsAssessors or internal audit may expect traceable mapping decisions, load logs, reconciliation reports and access records, which add build and retention work.Ask early which evidence the organization must retain, and design logging and reconciliation outputs to produce it by default.

Project phases and outputs

The sequence moves from understanding the legacy data to a verified production load and a runbook the operations team can use without the project team.

  1. Profile legacy data and scope sources

    We inventory the source systems, extracts and interfaces, then profile data volumes, code sets, duplicates and gaps against the FHIR resources in scope. The output is a data inventory and a scope statement that you approve before mapping begins.

  2. Design mappings and terminology decisions

    We map each source field to a FHIR resource, element and profile, and record decisions on code systems, value sets and how unmapped local codes are handled. Your clinical and data owners sign off the mapping specification, which becomes the reference for every transform.

  3. Build transforms and run a test load

    We build the extraction and transformation code, then load a sample into a non-production HAPI FHIR JPA server using FHIR transactions. Test environments may use the embedded H2 database, which is for trials only; production uses PostgreSQL or Microsoft SQL Server. The output is a working pipeline and a load log with rejected records explained.

  4. Run trial loads and validate results

    We run full trial loads from current extracts and check resource counts, referential links, validation outcomes and sample records against source. Each trial ends with a validation report that lists pass, fail and exception counts per resource type.

  5. Reconcile and clear defects

    We compare source and target totals, classify each difference as a mapping defect, source data issue or accepted exception, and fix the transforms in repeated cycles. The output is a reconciliation report signed by your data owners that records every accepted exception and its reason.

  6. Rehearse cutover and load production

    We rehearse the full cutover sequence in a staging environment that matches production configuration, including freeze, load, verification and rollback steps, then execute the production load under the agreed change window. The output is a completed load record and a verification summary against the reconciliation baseline.

  7. Hand over the runbook

    We deliver the migration runbook, transform code, mapping specification, reconciliation evidence and operating notes, and walk your operations team through them. Hand-over closes when your team has repeated a load or reconciliation step in their own environment, or when the gaps are logged for follow-up.

What to keep in-house and what to outsource

The table compares each phase of a HAPI FHIR migration by who should own it, which skills it requires and where a partner usually adds the most value, so you can compare the split with your own team's FHIR, Java and clinical capacity.

Migration partUsually in-houseOften outsourced or sharedSkills to check in your team
Clinical content decisions and sign-offClinicians, data owners and clinical informatics leads decide which codes, statuses and record types are migrated and in what formPartner facilitates workshops and documents decisions as mapping rules, but does not approve clinical contentClinical domain knowledge, data stewardship authority, ability to sign off on mapping decisions in writing
Source system extraction and accessInternal application or database owners extract data, grant read access and document source-side quirksLegacy vendor support may be needed for export tools or undocumented schemasSource database or API skills, knowledge of the legacy data model, change control on the source system
FHIR mapping and profile conformanceInternal architects review mappings and own the final profile choicesOften outsourced when the team lacks hands-on FHIR R4 or R5 experience and needs StructureDefinition and profile work doneFHIR resource modeling, profile authoring, terminology binding, familiarity with the target FHIR version
Transform code and transaction loadingInternal developers own repositories, pipelines and any code that must be maintained after handoverPartner may build initial transforms and bulk transaction loaders, with handover to internal engineersJava for HAPI FHIR client and server work, scripting for ETL, FHIR transaction Bundle construction, retry and idempotency design
Reconciliation and clinical safety checksClinicians review sampled records and sign off on discrepancies that affect carePartner builds count, field-level and referential comparison reports and runs them repeatedlySQL for source-to-target comparison, clinical safety review method, defect triage and sign-off criteria
Cutover operationsInternal operations and clinical leads own the go-live decision, freeze windows, rollback and downstream system switch-overPartner supports rehearsals, runbooks and on-call during the cutover window if contractedChange management, incident response, database administration on PostgreSQL or SQL Server, coordination with downstream consumers

What usually goes wrong

FHIR loads fail in predictable ways. Each risk below comes with a prevention step to build into the plan before the first load runs.

Non-idempotent loads create duplicates

A load that is interrupted and rerun can insert the same clinical records twice if each resource is posted as a create. Use conditional create or conditional update keyed on a legacy source identifier, so a rerun resolves to the existing resource. Test a full rerun against a copy of the target before the production load.

Broken references between resources

Transaction bundles that are not ordered, or that use fullUrl values the server cannot resolve, leave references pointing at nothing. Encounters can load before their patients, and observations can lose their subjects. Build bundles in dependency order, assign each entry a unique urn:uuid fullUrl, and check reference resolution in a sample load.

Profile validation failures found late

Resources that pass basic parsing can still fail the profiles your server or implementation guide enforces, often only after thousands of records are queued. Run the target profiles against a representative extract early, and agree with the data owners which failures block a load and which are logged for later correction.

Local codes mismatched to standard code systems

Legacy codes for diagnoses, observations or units often have no clean match in the code systems the target profiles require. Unmapped or wrongly mapped codes load without error and then break search and reporting. Maintain a versioned mapping table, record the code system and version used for each mapping, and have clinical owners sign off on high-volume codes.

Identity matching errors across patient records

Matching the same person across the legacy system and the new server on name and birth date alone merges distinct patients or splits one patient into several. Define the matching rules and thresholds before loading, review a sample of probable matches by hand, and keep the source identifiers so mistakes can be traced and reversed.

Embedded H2 database carried into production

The JPA server starter defaults to an embedded H2 database, which is convenient for a trial load and unsuitable for production health data. Teams that load into H2 for speed often keep it. Choose PostgreSQL or Microsoft SQL Server for the migration target from the start, and confirm the schema, backups and sizing on that database before loading.

Reconciliation that counts but does not compare

Matching resource counts between source and target can hide wrong values, missing fields and misattributed references. A total can be correct while every date is shifted or every allergy is dropped. Reconcile counts, then sample records field by field against the source, and check referential integrity with queries that look for references to missing resources.

Load runs without a rollback path

A bulk load that writes into the production server with no tested way to remove or correct it leaves a clean-up problem in live clinical data. Plan how a failed batch is identified, which source identifiers allow deletion or correction, and rehearse that procedure on the staging server before the production run.

How the work changes by starting point

Source systems that were never built around FHIR usually carry the most profiling and mapping work. The data model, code sets and free-text fields have to be understood before any FHIR resource can be produced.

  • Profiling effort: Expect a heavier discovery phase to find duplicate patients, inconsistent codes, missing identifiers and fields that hold more than one concept.
  • Mapping effort: Each source table or flat-file column needs a documented target resource, profile and element, with an owner who signs off on clinical meaning.
  • Terminology: Local codes must map to standard code systems. Ask who maintains that map and how unmapped values are handled at load time.
  • Confirm with the platform owner: Which FHIR version and profiles the server will validate against, and whether the target database is PostgreSQL or Microsoft SQL Server.

What you need to provide

Most delays in a HAPI FHIR migration come from inputs that were assumed rather than agreed. Before mapping starts, your team needs to supply read access to each source system and a workable extract approach, whether that is a database view, an HL7 v2 feed, a bulk export from another FHIR server or flat files. Confirm early who can approve extracts from production, and whether the source team will support questions during the mapping sprints.

Each source field also needs a data dictionary entry and a named clinical or business owner who can say what the value means and whether it is reliable. Mapping decisions such as how a legacy status code becomes an Encounter status or how free-text allergies become AllergyIntolerance resources cannot be settled by the integration team alone. Assign these owners before the first mapping review, because each unanswered field becomes a blocked mapping row.

You also need to decide the target FHIR version (for example R4 or R5) and which implementation guides or profiles your organization must conform to. HAPI FHIR JPA supports DSTU2, DSTU3, R4, R4B and R5, so this choice shapes the resource structures, validation rules and terminology bindings you test against. Make the decision in writing before mapping, since changing it later means re-mapping and re-validating everything already built.

On the infrastructure side, provision the HAPI FHIR JPA server with PostgreSQL or Microsoft SQL Server, since MySQL is not supported and the embedded H2 default is not intended for production. Also name owners for clinical sign-off and cutover, and agree in writing the reconciliation criteria (record counts, identifier matching, and which field-level differences are acceptable). Non-production work needs test patient data or an approved de-identification method, so privacy approval should be obtained before any real extract reaches a development environment.

Frequently asked questions

What drives the cost of a HAPI FHIR migration project?

The largest cost drivers are the number and complexity of source data types, the mapping work from legacy structures to FHIR resources, and the volume of data that needs validation. Costs come from the partner's engineering, analysis and testing time, plus your own staff time for clinical review and source system access. Most migration costs are one-time, while hosting, database and Java operations recur after go-live. Ask any quote to itemize discovery, mapping, loading, reconciliation, cutover and handover, and to state which items your team performs.

How long does a HAPI FHIR data migration take?

The duration is set by the written scope, and the same factors that drive cost also drive the schedule. The main drivers are the number of source systems, how many clinical data types must be mapped, the data quality of the legacy records, the number of validation and reconciliation cycles, and how many approvals clinical and IT owners must give before cutover. Parallel running periods and the availability of source extracts can also extend the timeline. Ask for a dated plan that lists each milestone and the client input each one depends on.

Can our own team migrate data into HAPI FHIR without a partner?

Yes, a team with FHIR, Java and database experience can attempt it, since HAPI FHIR is licensed under Apache 2.0 and its server, starter and documentation are publicly available. The harder work is clinical mapping, terminology decisions, duplicate resolution and evidence of reconciliation, which need clinical input and a repeatable test process. Check whether your team can run the JPA server on a supported Java version, write and test FHIR transactions, and govern mapping decisions with clinicians. A fixed-scope engagement can take on defined parts of this work, with the split agreed in writing.

Can HAPI FHIR load data directly from a legacy EHR?

HAPI FHIR does not read legacy EHR databases or proprietary interfaces by itself. It loads FHIR resources through its REST API, typically in transaction bundles. Getting from the legacy system to those resources is the mapping layer, and that layer is the core of the project. It extracts source records, transforms them into valid FHIR resources against the profiles you choose, and handles codes, references and dates. Loading then runs through FHIR transactions, followed by validation and reconciliation against source counts. Scope it as a mapping and loading project from the start.

How does a migration handle duplicate patient records?

Duplicate handling is decided in scope, through matching rules and a master patient index strategy, before any load runs. HAPI FHIR includes MDM capabilities that can be configured for matching and linking, and the scope defines the thresholds, identifiers and manual review queues to use. Your clinical and data governance owners approve how merges, links and survivorship decisions are made, since those decisions affect patient safety. The migration records how each candidate duplicate was resolved and who signed off. Confirm the MDM configuration against the documentation for your HAPI FHIR release.

Does DeployOpen certify that migrated health data is compliant?

No. DeployOpen prepares systems, controls and evidence for compliance assessments, including records of mapping decisions, reconciliation results and access settings. Independent auditors and certification bodies issue any audit report, attestation or certification, based on their own assessment. The evidence package is built to support that assessment, but it does not replace it. Ask your auditor which evidence they expect before the migration is designed, so reconciliation reports and change records are kept from the start.

How DeployOpen delivers this service

DeployOpen plans, builds, validates and documents HAPI FHIR migration and data loading inside infrastructure you control, from source-to-FHIR mapping through reconciled loads. Engagements are fixed-scope, with the scope agreed in writing before work starts.

How we scope

  • The written scope names the source systems, the FHIR version and the resource types to be migrated.
  • Mapping rules from legacy fields to FHIR resources and profiles are listed as deliverables with agreed acceptance criteria.
  • The scope states the load method, reconciliation checks, cutover approach and the environments where loading runs.

How we build

  • Mappings are implemented and tested against representative extracts before any full-volume load is attempted.
  • Loads use FHIR transactions with logged identifiers, so failed batches can be found, corrected and re-run safely.
  • Validation runs check resource conformance and reconcile record counts and key clinical fields against the source system.

How we hand over

  • Handover includes mapping specifications, load scripts, reconciliation reports and a runbook for repeat or incremental loads.
  • Your team receives documented decisions on unmapped fields, code system translations and rejected records.
  • Knowledge transfer sessions cover how to rerun a load, roll back a batch and interpret reconciliation output.

How we support

  • Ongoing support, upgrades and continuous testing are available as retainers after the migration is complete.
  • Support can cover follow-up loads, mapping changes as source systems evolve and HAPI FHIR version upgrades.
  • Confirm with DeployOpen during scoping which post-cutover support terms apply and how they are priced in the written quote.

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.