Skip to content

Maciej Walkowiak

Hi! 👋 My name is Maciej Walkowiak, freelance software consultant based in Berlin, Germany. I specialise in Java and Spring Boot. I help companies in building well designed, easy to maintain and fast backend applications.

Latest blog posts

  • PostgreSQL and UUID as primary key

    Published on
    • Postgresql
    • Java

    UUIDs are often used as database table primary keys. They are easy to generate, easy to share between distributed systems and guarantee uniqueness.

    Considering the size of UUID it is questionable if it is a right choice, but often it is not up to us to decide.

    This article does not focus on "if UUID is the right format for a key", but how to use UUID as a primary key with PostgreSQL efficiently.

  • Dynamic Projections with Spring Data JPA

    Published on
    • Java
    • Spring Data Jpa
    • Spring Boot
    • Hibernate

    TIP

    Projection is a subset of an aggregate loaded from a repository for read-only purposes.

    Methods returning projections are typically defined on the repository level, making the repository interface aware of all possible types of projections used in the application.

    java
    package com.app.account.domain;
    
    public interface AccountRepository extends Repository<Account, String> {
        AccountBasic findAccountBasicById(String id);
        AccountComplete findAccountCompleteById(String id);
    }
    
    public record AccountBasic(String id, 
                               String iban,
                               String bic) {}
    
    public record AccountComplete(String id,
                           String iban,
                           String bic,
                           State state,
                           Type type,
                           LocalDateTime createdAt) {}

    This approach has some drawbacks:

    • if there is a projection that almost fits our use case, it is tempting to modify it and add needed field - at the same time defeating a bit the main purpose of projections - fetching only what's needed.
    • naming projections becomes a challenge - how to name them? AccountBasic? AccountLight? AccountData? All these names are quite meaningless.
    • repository becomes difficult to use as it contains a long list of method, and to find out which one should be used you need to visit every projection.
    • because projections are shared between use cases, they become a coupling point, making future refactoring more difficult.
    • projections must have the same visibility level as the repository, for example if repository is public, projections must be public too.

    Instead of making the repository aware of all types projections used by all the use cases, we can use dynamic projections.

  • Container logs with Spring Boot and Testcontainers

    Published on
    • Java
    • Testcontainers
    • Spring Boot

    In this article you will learn how to enable container debug logs with Testcontainers and Spring Boot and how to leverage Spring Framework flexibility to turn logs on and off with a custom @EnableContainerLogs annotation. As a side effect you'll learn a little about Spring Framework internals enabling Spring's magic ✨.

  • Reified Generics in Java?

    Published on
    • Java

    A common pattern in Java, whenever there is a need retrieve data from a database or deserialize JSON is to pass the target object class as a parameter.

    A good example is Jackson's ObjectMapper#readValue method with following signature:

    java
    public <T> T readValue(String content, Class<T> valueType) {
        ...
    }

    Passing class as a parameter looks repetitive. Since <T> defines the type, why do we need to pass Class<T>? Why it can't be simplified to:

    java
    public <T> T readValue(String content) {
        ...
    }

    And most importantly, how is Mockito able to find out the type of mock in such code?

    java
    Book book = mock();
    Person person = mock();

    What kind of sorcery is that?

  • Faster integration tests with reusable Testcontainers and Flyway

    Published on
    • Testcontainers
    • Flyway
    • Spring Boot

    INFO

    Advice given in this article is especially relevant to applications with hundreds of Flyway migration files.

    In Spring Boot & Flyway - clear database between integration tests I described how to ensure that each integration test starts with clean state - wipe out content from the database, and all database migrations applied from scratch. Such approach simplifies writing tests but comes with one significant drawback - running database migration takes time. The more migration files, the longer it takes. I still believe this is a solution worth considering for small services, but for large applications with hundreds or thousands of migrations, time needed to run migrations may become a biggest factor contributing to slow integration tests.

    In this article I'll explore how reusable containers can significantly speed up integration tests during development phase and how to configure Flyway to use them efficiently.

  • Running one-time jobs with Quartz and Spring Boot

    Published on
    • Spring Boot
    • Quartz
    • Scheduled

    Scheduling jobs with Quartz has been discussed numerous times. However, it is worth to know that Quartz can be used not just to run jobs every X hours or based on a CRON expression, but also to execute specific code once at a specified time in the future.

    I believe that in some specific use cases, following this approach can dramatically simplify your architecture and implementation. Let's see step by step how to do it.

  • The best way to use Testcontainers with Spring Boot

    Published on
    • Spring Boot
    • Java
    • Junit
    • Testcontainers

    "How to set up Testcontainers with Spring Boot" has already been described hundreds times. I am not going to write the same things that have already been said but rather discuss the pros and cons of the existing solutions and present one that works for me and I believe works for majority of projects.

    Specifically, I am looking for a solution that meets following criteria:

    • as little overhead as possible
      • containers are started only once for all tests
      • containers are started in parallel
    • no requirement for test inheritance
    • declarative usage
  • Spring Boot & Flyway - clear database between integration tests

    Published on
    • Spring Boot
    • Java
    • Junit
    • Flyway

    To make sure that tests are repeatable and isolated, it is a good practice to ensure that they always start with a clean state. In unit testing this could be mocking dependencies, or setting certain properties on objects. In integration testing it often means bringing the database to a well known state - usually erasing all the tables, and inserting the data that the integration tests expect.

    In this short tutorial you'll see how to clean a database between integration tests. The recipe assumes that you use: relational database (like MySQL or PostgreSQL), Spring Boot, Flyway - for database migrations, JUnit 5.

    Even if you don't use exactly these technologies, overall idea is quite generic, so I am sure you can adjust it to your needs.

    You will also learn the following:

    • why it is important to clear the database in integration tests
    • how to clear the database using JdbcTemplate, Spring Data repositories and Flyway
    • how to create custom JUnit 5 extension
    • how to create JUnit 5 meta-annotations
  • What's new in Spring?

    Published on
    • Spring
    • Spring Boot
    • Java

    Agent Smith from The Matrix

    If you feel a little overwhelmed with the constant stream of news from the Spring team - I hear you. November was a very hot month for Spring developers. In addition to plenty of Spring project portfolio releases there were few interesting changes that you might have missed.

    Below I collected the most important things (and added some notes) that I believe you - as a Spring developer - should know to stay up to date.

Let's stay in touch and follow me on Twitter: @maciejwalkowiak

Subscribe to RSS feed