spring-data-relational icon indicating copy to clipboard operation
spring-data-relational copied to clipboard

Custom class is registered as simple type only if there is writing converter

Open Infeligo opened this issue 3 years ago • 6 comments

I am using Spring Data JDBC repository to query data for report (hence, readonly). In one place I needed to convert from JSONB to a DTO. I registered a customer converter marked as @ReadingConverter for that purpose, but for some reason it was never called. Debugging the code, I noticed that my DTO is considered as an entity, although it should have been registered as a simple type. Debugging more I found out that only the source type of a @WritingConverter is registered as a simple type. Adding a dummy writing converter fixed the issue for me. However, this seems unexpected and the fix adds redundant code.

My code:

@Data
public class ReportDTO {

  private MyData myData;

}

@Configuration
public class JdbcConfig extends AbstractJdbcConfiguration

  private final ObjectMapper objectMapper = new ObjectMapper();

  @Bean
  @NonNull
  @Override
  public JdbcCustomConversions jdbcCustomConversions() {
    return new JdbcCustomConversions(
        List.of(
            new JsonbToMyData(objectMapper),
        )
    );
  }


  @ReadingConverter
  @RequiredArgsConstructor
  static class JsonbToMyData implements Converter<PGobject, MyData> {

    private final ObjectMapper objectMapper;

    @Override
    public MyData convert(PGobject source) {
      try {
        return objectMapper.readValue(source.getValue(), MyData.class);
      } catch (JsonProcessingException e) {
        throw new RuntimeException(e);
      }
    }

  }

Infeligo avatar Mar 08 '22 21:03 Infeligo

The behaviour you describe is a bug and should get fixed. The type should NOT be considered a simple type, but custom conversions should be taken into consideration before treating it as an entity.

schauder avatar Mar 10 '22 10:03 schauder

The type should NOT be considered a simple type

But all source types of writing converters always add to custom simple types. Moreover, all custom types in BasicRelationalConverter are treated as simple:

if (converterRegistration.isWriting()) {

	writingPairs.add(pair);
	customSimpleTypes.add(pair.getSourceType());    // <<<<<<<<<<<<<<<<<<<<

	if (logger.isWarnEnabled() && !converterRegistration.isSimpleTargetType()) {
		logger.warn(String.format(WRITE_CONVERTER_NOT_SIMPLE, pair.getSourceType(), pair.getTargetType()));
	}
}

Custom simple types is Set<Class<?>>.

Why not just add this type when registering a converter for reading? The simple types set will not contain repetitions.

loolzaaa avatar Sep 30 '22 08:09 loolzaaa