0

In my Spring Boot Webflux project, I'm using Spring Data R2DBC for reactive data access. The project involves fetching data from a relational database, where some tables have columns containing JSON data that represent nested objects.

My current approach is to fetch the data and then manually parse the JSON into my POJO using custom read converters. However, this process becomes cumbersome when I have multiple nested objects and differing structures.

Here's a simplified example of what I've been doing:

@UtilityClass
public class ConverterHelper {
    // ObjectMapper initialization

    public static <T> T readJson(Row row, String field, Class<T> clazz) {
        // implementation
    }
}

@ReadingConverter
public class CustomReadingConverter implements Converter<String, Object> {
    // implementation
}

@Configuration
public class R2dbcConfiguration extends AbstractR2dbcConfiguration {
    // implementation
}

The question I have is: Is there a more generic way to handle this, similar to how Spring Data JPA automatically maps nested objects? I'd prefer not to write custom converters every time I encounter this situation.

I understand that JPA or Hibernate might handle these scenarios more gracefully, but those aren't suitable for my project as I need the non-blocking I/O provided by R2DBC. Is there a solution to this in the realm of Spring Data R2DBC, or am I confined to using custom converters for these complex/nested objects?

Any suggestions or insights would be greatly appreciated.

Tobiq
  • 2,489
  • 19
  • 38

1 Answers1

0

I've done this in another way by using a json field and then converting to whatever object I needed in a mapping step.

For example, I might have an entity like this:

import io.r2dbc.postgresql.codec.Json;

@Table("table_name")
@Data
@Builder
public class MyObject {
    @Id
    private Integer id;
    private Json data;
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;
}

With a DTO class like

@Data
@Builder
public class MyObjectDTO {
    private Integer id;
    private YourNestedObjectType data;
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;
}

And then a mapping class that does something like this:

public MyObjectDTO to(MyObject myObj) {
    try {
        ObjectMapper objectMapper = 
        YourNestedObjectType somethingNested = objectMapper.readValue(
            myObj.getData().asString(), 
            YourNestedObjectType.class);

        return MyObjectDTO.builder()
                .id(myObj.getId())
                .data(somethingNested)
                .createdAt(myObj.getCreatedAt())
                .updatedAt(myObj.getUpdatedAt())
                .build();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

with the understanding that YourNestedObjectType can be a wrapper class that holds other classes like

public class YourNestedObjectType {
   private String field1;
   private List<OtherObject> otherObjects;
}
BeLEEver
  • 251
  • 4
  • 11