Search code examples
javajooqimmutables-library

Map jooq records to Immutables


There is a nice option of automatically, typesafe map jooq result to Java POJO e.g. using Java 16 records described here

I want to use objects created with Immutables library. I can create factory method using @Parameter annotation and it works fine

@Value.Immutable
public interface Author {
    @Value.Parameter
    int id();

    @Value.Parameter
    String firstName();

    @Value.Parameter
    Optional<String> lastName();
    
    @Value.Parameter
    Book[] books();
}

@Value.Immutable
public interface Book {
    @Value.Parameter
    int id();

    @Value.Parameter
    int title();
}

and the query

create.select(
         AUTHOR.ID,
         AUTHOR.FIRST_NAME, 
         AUTHOR.LAST_NAME,
         array(
           select(row(BOOK.ID, BOOK.TITLE).mapping(Book.class, ImmutableBook::of))
           .from(BOOK)
           .where(BOOK.AUTHOR_ID.eq(AUTHOR.ID)
         )
       )
      .from(AUTHOR)
      .fetch(Records.mapping(ImmutableAuthor::of));

but the problem appears when some of parameters are nullable - lastName in this case as factory method of() requires Optional.empty() for nullable field.


Solution

  • Solution is to use @Value.Style annotation so immutable object look like:

    @Value.Immutable
    @Value.Style(allParameters = true, optionalAcceptNullable = true)
    public interface Author {
        @Value.Parameter
        int id();
    
        @Value.Parameter
        String firstName();
    
        @Value.Parameter
        Optional<String> lastName();
        
        @Value.Parameter
        Book[] books();
    }
    
    @Value.Immutable
    @Value.Style(allParameters = true, optionalAcceptNullable = true)
    public interface Book {
        @Value.Parameter
        int id();
    
        @Value.Parameter
        int title();
    }
    
    • optionalAcceptNullable allows to set null for optional fields
    • allParameters acts like marking all properties/methods with @Value.Parameter

    Notice - order of fields in SQL needs to match order of methods in immutable interface