Using Micrometer to trace your Spring Data JPA application
--
In a previous article, we saw the goodness of stirring a little Micrometer into our Spring Boot 3 application to trace what our application did. We saw how to activate the Micrometer bindings buried deep in Spring Boot for web calls. And we piped all those good metrics into Zipkin, the open source distributed tracing system thanks to Docker.
But that wasn’t very “realistic” cuz we didn’t have a “real” database underneath it.
Everyone know that real apps have data, right? So why not put something together!
To kick things off, after fashioning an app using start.spring.io, Spring Data JPA, and H2, we need a domain object. Let’s craft something like this:
@Entity
public class Employee {
@Id
@GeneratedValue private Long id;
private String name;
private String role;
//...constructors/getters/setters ommitted for brevity...
}
A basic domain object that lets us model the Employees in our payroll system. This entity class is properly annotated with @jakarta.persistence.Entity (remember Spring Boot 3 is on Jakarta EE 10!). It also has the id field marked up as the primary key using @jakarta.persistence.Id. We will also let the JPA persistence provider handle primary key generation by using @jakarta.persistence.GeneratedValue.
Even though Spring Data provides some cool features, we STILL have to model our entity classes properly for things to come together!
Since we’re using Spring Data JPA, we also need to define a repository. So let’s do something like this:
public interface EmployeeRepository extends JpaRepository<Employee, Long> {}
This barebones interface definition extends Spring Data JPA’s JpaRepository and defines its domain type as Employee and the primary key type as Long. Even though our interface definition is empty, it still comes packed with LOTS of options. (Just visit JpaRepository and its parent interfaces inside your IDE to see exactly what you get!)
The rest of the application is just a Spring MVC @RestController, much like what we had in the previous article, shown below:
@RestController
public class EmployeeController {
private final EmployeeRepository repository;
public EmployeeController(EmployeeRepository repository) {
this.repository = repository;
}
@GetMapping("/api/employees")
List<Employee>…