Spring Data Commons implementation for HAPI FHIR (Part 1)

Kostiantyn Ivanov
4 min readSep 2, 2023

--

What we will learn?

  • What is s Spring Data Commons
  • What is HAPI FHIR
  • How to create our own spring data implementations (like Spring Data JPA or Spring Data MongoDB) and make our integrations easier and more generic

Spring Data Commons overview

Spring Data Commons is a module within the larger Spring Data project, which is part of the Spring Framework ecosystem. Spring Data is designed to simplify data access and manipulation in Java applications, particularly those built using the Spring Framework.

Key features Spring Data Commons

Repository Abstraction:

Spring Data Commons defines the Repository interface, which acts as a common interface for working with data stores. Developers can extend this interface and create custom repositories for their specific data models. This interface has extensions for CRUD (Create, Read, Update, Delete) operations and and their batch analogue.

The CRUD interface, for example, looks like this:

@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {
<S extends T> S save(S entity);

<S extends T> Iterable<S> saveAll(Iterable<S> entities);

Optional<T> findById(ID id);
...
}

Pagination and Sorting:

Spring Data Commons provides separate interface for pagination and sorting of query results, which can be especially useful when dealing with large datasets.

The PagingAndSorting interface like this:

@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID> extends Repository<T, ID> {
Iterable<T> findAll(Sort sort);

Page<T> findAll(Pageable pageable);
}

It’s not actually necessarily that your implementation will support all these interfaces, but it’s still good to have some template.

Query Methods:

Spring Data Commons provides interfaces for method names parsing. Inside our parsers we can generate native queries based on the data we retrieve from a method name. As a result our framework will support “magic methods” like this:

public interface IFooDAO extends JpaRepository<Foo, Long> {

Foo findByNameAndTitleOrAgeGt(String name, String title, int age);

}

Also we have a built-in validation of the method names according to a entity class metadata.

Custom Query Execution:

Developers can write custom query methods or use native queries when the generated queries are insufficient for their needs.

This function provided us by next annotations

@QueryAnnotation well-known extensions you can find in all existing Spring Data implementations. For example:

package org.springframework.data.elasticsearch.annotations;

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
@Documented
@QueryAnnotation
public @interface Query {
@AliasFor("query")
String value() default "";
@AliasFor("value")
String query() default "";
boolean count() default false;
}

Finally it will be used in the way like this:

@Query("SELECT u FROM User u WHERE u.status = :status and u.name = :name")
User findUserByUserStatusAndUserName(@Param("status") Integer userStatus,
@Param("name") String userName);

SpEL (Spring Expression Language) Support:

Spring Expression Language is something that we use widely in our Spring applications. Just to remind here are few examples of usage

@Value("#{1 == 1}")
private boolean equal;

@Value("#{250 > 200 && 200 < 4000}")
private boolean and;

@Value("#{someBean.someProperty != null ? someBean.someProperty : 'default'}")
private String ternary;

Spring Expression Language can be used in query methods to specify more complex and dynamic queries:

@Query("select u from User u where u.age = ?#{[0]}")
List<User> findUsersByAge(int age);

@Query("select u from User u where u.firstname = :#{#customer.firstname}")
List<User> findUsersByCustomersFirstname(@Param("customer") Customer customer);

Auditing and Event Handling:

Auditing and Event Handling includes support for auditing and event handling, which can automatically track changes to entities or trigger events when certain actions occur.

It provided us by few classes from Spring Data Commons

And gives us ability to create some auditing events which we will be able to listen from our client code:

public class AuditorAwareImpl implements AuditorAware<String> {

@Override
public String getCurrentAuditor() {
// your custom logic
}

}

Next part:
Spring Data Commons implementation for HAPI FHIR (Part 2)

--

--