How To Map String To Boolean in Spring Data JPA

Overview

There are times you work with legacy databases that store boolean values as strings. Let’s consider this example: Town A conducted a survey to see if their citizens like apples or not. The developer back then created a table like this:

CREATE TABLE apple_survey
(
    id         serial      not null primary key,
    name       varchar(50) not null,
    like_apple varchar(5) NOT NULL
)

For the file like_apple, he planned to store LIKE and DONOT as values (who knows why he did that). The task now is to map the such string to boolean values so other developers can create API interacting with that legacy data.

It turned out, JPA has quite an elegant support for this case. Let’s find out how to convert string to boolean and vice versa.

Using @Converter

To convert between two data types in JPA, you need to create a converter. In this case, this is the implementation:

package com.learn.springdata.model.survey;

import javax.persistence.AttributeConverter;
import javax.persistence.Converter;

@Converter(autoApply = false)
public class LikeConverter implements AttributeConverter<Boolean, String> {
    @Override
    public String convertToDatabaseColumn(Boolean aBoolean) {
        return aBoolean ? "LIKE" : "DONOT";
    }

    @Override
    public Boolean convertToEntityAttribute(String s) {
        return s != null && s.equalsIgnoreCase("LIKE");
    }
}

To define a JPA converter, you need to:

  • Create a class and annotate it will @Converter
  • Make that class implement the interface AttributeConverter.

You may notice autoApply is set to false. This prevents the converter from applying to all fields (since this situation involves only one field).

Next, in the entity class, specify that the boolean field needs this converter to work properly:

package com.learn.springdata.model.survey;

import lombok.Getter;
import lombok.Setter;

import javax.persistence.Column;
import javax.persistence.Convert;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Getter
@Setter
@Table(name = "apple_survey")
public class SurveyPerson {
    @Id
    @GeneratedValue
    private long id;

    private String name;

    @Convert(converter = LikeConverter.class)
    @Column(name = "like_apple")
    private boolean likeApple;
}

You specify the converter by annotating the field you want to convert with @Convert and specify the converter class.

This is all you need to do. Next, let’s see how the conversion work.

Test the converter

Let’s create a controller to accept POST and GET requests to demonstrate setting and getting data to and from the database.

package com.learn.springdata.controller.survey;

import com.learn.springdata.model.survey.SurveyPerson;
import com.learn.springdata.repo.survey.SurveyPersonRepository;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/surveys")
public class SurveyPersonController {

    private final SurveyPersonRepository repository;

    public SurveyPersonController(SurveyPersonRepository repository) {
        this.repository = repository;
    }

    @PostMapping
    public SurveyPerson save(@RequestBody SurveyPerson person) {
        return repository.save(person);
    }

    @GetMapping("/list")
    public List<SurveyPerson> getAll() {
        return repository.findAll();
    }
}

As you can see, I created two endpoints to create and list the records here. First, let’s create some records using Postman:

Create a new record using standard REST endpoint
Create a new record using standard REST endpoint

Now, let’s try the list endpoint:

Get all entries from the database
Get all entries from the database

The API works as expected. Let’s check the data in the database:

Data stored as string in the database
Data stored as string in the database

As you can see, in the database, data for the field like_apple is still stored as a string.

Conclusion

As you can see, by using the @Converter, @Convert, and the AttributeConverter interface, it was quite easy to convert String to Boolean and back with Spring Data JPA.

As usual, the code for this article is available on Github.

Leave a Comment