[GSoC][LibreHealth] First week of Coding Period

Yash Saraf
3 min readMay 21, 2018

--

During the community bonding period, I was assigned the task of getting the HAPI FHIR JPA server example to work with Spring Data Cassandra.

I approached this task by first getting the app to work with Spring Data JPA. After a lot of trial and error I noticed that HAPI FHIR Restful server uses something called Resource Providers as a layer between the controller and DAO layers. This means that instead of replacing the whole DAO layer, I could just switch out the existing resource providers for the ones that used Spring Data Repositories completely ignoring the existing DAO layer.

This is how an example resource provider looks like,

public class PatientResourceProvider implements IResourceProvider {  private PatientRepository patientRepository;  public PatientResourceProvider(PatientRepository patientRepository) {
this.patientRepository = patientRepository;
}
@Override
public Class<? extends IBaseResource> getResourceType() {
return Patient.class;
}
@Search(allowUnknownParams = true)
public Bundle search(search params...) {
Bundle bundle = new Bundle();
// Use `patientRepository` object to retrieve the data according to search params
// Add results to bundle
return bundle;
}

Where PatientRepository is a simple Spring Data Repository, like so

public interface PatientRepository extends CrudRepository<Patient, Integer> {
}

Here the app started throwing the error that it could not recognize the HAPI FHIR DSTU3 structures as managed type. The issue was that hibernate could not recognize the HAPI models because they weren’t annotated with @Entity. I used hibernate mapping files in this case (similar results could’ve been achieved using JPA persistence mapping XML as well I presume.)

My next step, was to get the app working with Spring Data Cassandra instead of Spring Data JPA. Here the things started to get awry since Hibernate doesn’t officially support cassandra so Hibernate mapping files didn’t work and neither did JPA mapping files.

So I decided to make a standalone spring boot app to test spring data cassandra with HAPI FHIR structures. First I quickly setup a cassandra docker environment and connected it to the app. Then I connected cassandra instance to the app and configured the app to create the keyspace specified if it didn’t already exist. I also configured the app to recreate the whole schema from the models every time the app starts.

But I kept getting Unconfigured table errors when using HAPI structures. Going through the spring data cassandra docs revealed that there isn’t an XML style configuration for declaring Tables and Primary keys in spring data cassandra other than using the annotations @Table and @Id or @PrimaryKey. I of course could not annotate the structures directly since they’re a third party dependency. So I tried a few other work arounds, such as extending the structures and annotating the getters/setters instead, none of which seems to work till now. I did get the app to start by cloning the structures locally (which I know isn’t a solution, I needed to see if annotations were the only issue), but there were mapping errors since Cassandra was unable to read some custom data types.

As a solution for this Spring Data Cassandra provides custom converters which is a set of two classes that help Cassandra to convert non-primitive data types to primitive ones. Here’s an example,

public class BooleanTypeConverter {

public static class BooleanTypeReadConverter implements Converter<Boolean, BooleanType> {

@Override
public BooleanType convert(Boolean aBoolean) {
BooleanType booleanType = new BooleanType();
booleanType.setValue(aBoolean);
return booleanType;
}
}

public static class BooleanTypeWriteConverter implements Converter<BooleanType, Boolean> {

@Override
public Boolean convert(BooleanType booleanType) {
return booleanType.booleanValue();
}
}
}

Adding such converters to the Cassandra configuration solved the data type mapping problem, but the annotation problem still exists. I will hopefully be able to solve this soon, the very last and not so clean resort would be to clone the HAPI FHIR structures and modify them locally.

--

--