Getting HttpMessageNotWritableException when trying to return List in response body in SpringBoot

I’m getting following error if I try to return List which I get from field in my entity class. If I create List myself then I don’t get this error. I’m using SpringBoot 3.3.2 with Java 17.

Error:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>{
"message": "Exception occurred: HttpMessageNotWritableException: Could not write JSON: class java.lang.String cannot be cast to class java.util.UUID (java.lang.String and java.util.UUID are in module java.base of loader 'bootstrap')",
}
</code>
<code>{ "message": "Exception occurred: HttpMessageNotWritableException: Could not write JSON: class java.lang.String cannot be cast to class java.util.UUID (java.lang.String and java.util.UUID are in module java.base of loader 'bootstrap')", } </code>
{
  "message": "Exception occurred: HttpMessageNotWritableException: Could not write JSON: class java.lang.String cannot be cast to class java.util.UUID (java.lang.String and java.util.UUID are in module java.base of loader 'bootstrap')",
}

Controller Class
For testing purpose, I’m calling OrderRequestEntity directly from here and I’ve made sure that entity exists in database for given UUID. You can find OrderRequestEntity class after TestDto1, TestDto2 and GenericResponse in this post.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code> @GetMapping("/res1")
private ResponseEntity<GenericResponse<TestDto1>> responseTest1(@RequestParam Integer num) {
TestDto2 testDto2 = new TestDto2();
List<UUID> uuidList = new ArrayList<>();
switch (num) {
case 1: {
uuidList.add(UUID.randomUUID());
uuidList.add(UUID.randomUUID());
break;
}
case 2: {
OrderRequestEntity entity = orderRequestRepository.findById(UUID.fromString("158790c2-ce63-4d00-b053-33f5a72782e7")).orElse(null);
uuidList = entity.getItems();
}
}
testDto2.setId(UUID.randomUUID());
testDto2.setUuidList2(uuidList);
TestDto1 testDto1 = new TestDto1();
testDto1.setId(UUID.randomUUID());
testDto1.setTestDto2(testDto2);
return ResponseEntity.ok(new GenericResponse<>(true, "response got", testDto1));
}
</code>
<code> @GetMapping("/res1") private ResponseEntity<GenericResponse<TestDto1>> responseTest1(@RequestParam Integer num) { TestDto2 testDto2 = new TestDto2(); List<UUID> uuidList = new ArrayList<>(); switch (num) { case 1: { uuidList.add(UUID.randomUUID()); uuidList.add(UUID.randomUUID()); break; } case 2: { OrderRequestEntity entity = orderRequestRepository.findById(UUID.fromString("158790c2-ce63-4d00-b053-33f5a72782e7")).orElse(null); uuidList = entity.getItems(); } } testDto2.setId(UUID.randomUUID()); testDto2.setUuidList2(uuidList); TestDto1 testDto1 = new TestDto1(); testDto1.setId(UUID.randomUUID()); testDto1.setTestDto2(testDto2); return ResponseEntity.ok(new GenericResponse<>(true, "response got", testDto1)); } </code>
    @GetMapping("/res1")
    private ResponseEntity<GenericResponse<TestDto1>> responseTest1(@RequestParam Integer num) {
        TestDto2 testDto2 = new TestDto2();
        List<UUID> uuidList = new ArrayList<>();
        switch (num) {
            case 1: {
                uuidList.add(UUID.randomUUID());
                uuidList.add(UUID.randomUUID());
                break;
            }
            case 2: {
                OrderRequestEntity entity = orderRequestRepository.findById(UUID.fromString("158790c2-ce63-4d00-b053-33f5a72782e7")).orElse(null);
                uuidList = entity.getItems();
            }
        }

        testDto2.setId(UUID.randomUUID());
       testDto2.setUuidList2(uuidList);

        TestDto1 testDto1 = new TestDto1();
        testDto1.setId(UUID.randomUUID());
        testDto1.setTestDto2(testDto2);
        return ResponseEntity.ok(new GenericResponse<>(true, "response got", testDto1));
    }

TestDto1

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TestDto1 {
private UUID id;
private TestDto2 testDto2;;
}
</code>
<code> @Data @AllArgsConstructor @NoArgsConstructor public class TestDto1 { private UUID id; private TestDto2 testDto2;; } </code>

@Data
@AllArgsConstructor
@NoArgsConstructor
public class TestDto1 {
    private UUID id;
    private TestDto2 testDto2;;
}

TestDto2

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>@Data
@AllArgsConstructor
@NoArgsConstructor
public class TestDto2 {
private UUID id;
private List<UUID> uuidList2;
private Point point1;
private Point point2;
}
</code>
<code>@Data @AllArgsConstructor @NoArgsConstructor public class TestDto2 { private UUID id; private List<UUID> uuidList2; private Point point1; private Point point2; } </code>
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TestDto2 {
    private UUID id;
    private List<UUID>  uuidList2;
    private Point point1;
    private Point point2;
}

GenericResponse

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>@Data
@NoArgsConstructor
@AllArgsConstructor
public class GenericResponse<T> {
private boolean success;
@JsonInclude(JsonInclude.Include.NON_NULL)
private String message;
private String correlationId = MDC.get("correlationId");
private T data;
public GenericResponse(boolean success, String message, T data) {
this.success = success;
this.message = message;
this.data = data;
}
public GenericResponse(T data) {
this.success = true;
this.data = data;
}
}
</code>
<code>@Data @NoArgsConstructor @AllArgsConstructor public class GenericResponse<T> { private boolean success; @JsonInclude(JsonInclude.Include.NON_NULL) private String message; private String correlationId = MDC.get("correlationId"); private T data; public GenericResponse(boolean success, String message, T data) { this.success = success; this.message = message; this.data = data; } public GenericResponse(T data) { this.success = true; this.data = data; } } </code>
@Data
@NoArgsConstructor
@AllArgsConstructor
public class GenericResponse<T> {
    private boolean success;
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private String message;
    private String correlationId = MDC.get("correlationId");
    private T data;

    public GenericResponse(boolean success, String message, T data) {
        this.success = success;
        this.message = message;
        this.data = data;
    }

    public GenericResponse(T data) {
        this.success = true;
        this.data = data;
    }
}

OrderRequestEntity (Here the field which I’m interested in is “items”, for which I’ve written converter to convert it to JSON when we’re storing it in DB and back to List when we’re trying to get items from the entity).

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>@Data
@Entity
@Table(name = "order_request")
public class OrderRequestEntity {
@Id
@GeneratedValue
@Column(name = "id")
private UUID id;
@Column(name = "restaurant_location", columnDefinition = "Geometry(Point, 4326)")
private Point restaurantLocation;
@Column(name = "delivery_location", columnDefinition = "Geometry(Point, 4326)")
private Point deliveryLocation;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "customer_id")
private CustomerEntity customerEntity;
@Column(name = "customer_id", updatable = false, insertable = false)
private UUID customerId;
@Column(name = "restaurant_id")
private UUID restaurantId;
@Convert(converter = UUIDListConvertor.class)
@Column(name = "items")
private List<UUID> items;
@Enumerated(EnumType.STRING)
@Column(name = "payment_type")
private PaymentType paymentType;
@Enumerated(EnumType.STRING)
@Column(name = "order_request_status")
private OrderRequestStatusType orderRequestStatusType;
@Column(name = "created_on")
private Instant createdOn;
@Column(name = "updated_on")
private Instant updatedOn;
@PrePersist
protected void onCreate() {
this.createdOn = this.updatedOn = Instant.now();
}
@PreUpdate
protected void onUpdate() {
this.updatedOn = Instant.now();
}
}
</code>
<code>@Data @Entity @Table(name = "order_request") public class OrderRequestEntity { @Id @GeneratedValue @Column(name = "id") private UUID id; @Column(name = "restaurant_location", columnDefinition = "Geometry(Point, 4326)") private Point restaurantLocation; @Column(name = "delivery_location", columnDefinition = "Geometry(Point, 4326)") private Point deliveryLocation; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "customer_id") private CustomerEntity customerEntity; @Column(name = "customer_id", updatable = false, insertable = false) private UUID customerId; @Column(name = "restaurant_id") private UUID restaurantId; @Convert(converter = UUIDListConvertor.class) @Column(name = "items") private List<UUID> items; @Enumerated(EnumType.STRING) @Column(name = "payment_type") private PaymentType paymentType; @Enumerated(EnumType.STRING) @Column(name = "order_request_status") private OrderRequestStatusType orderRequestStatusType; @Column(name = "created_on") private Instant createdOn; @Column(name = "updated_on") private Instant updatedOn; @PrePersist protected void onCreate() { this.createdOn = this.updatedOn = Instant.now(); } @PreUpdate protected void onUpdate() { this.updatedOn = Instant.now(); } } </code>
@Data
@Entity
@Table(name = "order_request")
public class OrderRequestEntity {
    @Id
    @GeneratedValue
    @Column(name = "id")
    private UUID id;

    @Column(name = "restaurant_location", columnDefinition = "Geometry(Point, 4326)")
    private Point restaurantLocation;

    @Column(name = "delivery_location", columnDefinition = "Geometry(Point, 4326)")
    private Point deliveryLocation;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "customer_id")
    private CustomerEntity customerEntity;

    @Column(name = "customer_id", updatable = false, insertable = false)
    private UUID customerId;

    @Column(name = "restaurant_id")
    private UUID restaurantId;

    @Convert(converter = UUIDListConvertor.class)
    @Column(name = "items")
    private List<UUID> items;

    @Enumerated(EnumType.STRING)
    @Column(name = "payment_type")
    private PaymentType paymentType;

    @Enumerated(EnumType.STRING)
    @Column(name = "order_request_status")
    private OrderRequestStatusType orderRequestStatusType;

    @Column(name = "created_on")
    private Instant createdOn;

    @Column(name = "updated_on")
    private Instant updatedOn;

    @PrePersist
    protected void onCreate() {
        this.createdOn = this.updatedOn = Instant.now();
    }

    @PreUpdate
    protected void onUpdate() {
        this.updatedOn = Instant.now();
    }
}

UUIDListConvertor

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>@Converter
public class UUIDListConvertor extends JsonConverter<List<UUID>> {
}
</code>
<code>@Converter public class UUIDListConvertor extends JsonConverter<List<UUID>> { } </code>
@Converter
public class UUIDListConvertor extends JsonConverter<List<UUID>> {

}

JsonConverter

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>@Converter
public class JsonConverter<T> implements AttributeConverter<T, String> {
private final TypeReference<T> typeReference = new TypeReference<T>() {};
private final ObjectMapper objectMapper = new ObjectMapper();
@Override
public String convertToDatabaseColumn(T object) {
try {
return objectMapper.writeValueAsString(object);
} catch (JsonProcessingException e) {
throw new IllegalArgumentException("Failed to serialize JSON data", e);
}
}
@Override
public T convertToEntityAttribute(String json) {
try {
return objectMapper.readValue(json, typeReference);
} catch (JsonProcessingException e) {
throw new IllegalArgumentException("Failed to deserialize JSON data", e);
}
}
}
</code>
<code>@Converter public class JsonConverter<T> implements AttributeConverter<T, String> { private final TypeReference<T> typeReference = new TypeReference<T>() {}; private final ObjectMapper objectMapper = new ObjectMapper(); @Override public String convertToDatabaseColumn(T object) { try { return objectMapper.writeValueAsString(object); } catch (JsonProcessingException e) { throw new IllegalArgumentException("Failed to serialize JSON data", e); } } @Override public T convertToEntityAttribute(String json) { try { return objectMapper.readValue(json, typeReference); } catch (JsonProcessingException e) { throw new IllegalArgumentException("Failed to deserialize JSON data", e); } } } </code>
@Converter
public class JsonConverter<T> implements AttributeConverter<T, String> {
    private final TypeReference<T> typeReference = new TypeReference<T>() {};
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public String convertToDatabaseColumn(T object) {
        try {
            return objectMapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            throw new IllegalArgumentException("Failed to serialize JSON data", e);
        }
    }

    @Override
    public T convertToEntityAttribute(String json) {
        try {
            return objectMapper.readValue(json, typeReference);
        } catch (JsonProcessingException e) {
            throw new IllegalArgumentException("Failed to deserialize JSON data", e);
        }
    }
}

pom.xml

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-database-postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-spatial</artifactId>
<version>6.5.2.Final</version>
</dependency>
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>8.0</version>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.15.0</version>
</dependency>
</code>
<code> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> </dependency> <dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-database-postgresql</artifactId> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-spatial</artifactId> <version>6.5.2.Final</version> </dependency> <dependency> <groupId>org.modelmapper</groupId> <artifactId>modelmapper</artifactId> <version>3.2.1</version> </dependency> <dependency> <groupId>net.logstash.logback</groupId> <artifactId>logstash-logback-encoder</artifactId> <version>8.0</version> </dependency> <dependency> <groupId>jakarta.validation</groupId> <artifactId>jakarta.validation-api</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.15.0</version> </dependency> </code>

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-database-postgresql</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-spatial</artifactId>
            <version>6.5.2.Final</version>
        </dependency>
        <dependency>
            <groupId>org.modelmapper</groupId>
            <artifactId>modelmapper</artifactId>
            <version>3.2.1</version>
        </dependency>
        <dependency>
            <groupId>net.logstash.logback</groupId>
            <artifactId>logstash-logback-encoder</artifactId>
            <version>8.0</version>
        </dependency>
        <dependency>
            <groupId>jakarta.validation</groupId>
            <artifactId>jakarta.validation-api</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.15.0</version>
        </dependency>

Expected outcome is that List is properly set in TestDto2 and we get it in response as well. But when I set it from OrderRequestEntity, I get an error shared above. This error does not show up when we manually add uuids to the list. I suspect it is due to convertor which is associated with items field in OrderRequestEntity.

To check if that is the issue I used debugger and I observed that values are successfully getting set in the List uuidList2 of TestDto2 but at the time when program reaches the end to give response, error occurs.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật