Search code examples
spring-bootjooq

Jooq DataTypeException since Spring.Boot 2.4.x


I am getting a DataTypeException when retrieving data since the upgrade to Spring Boot 2.4.x. It worked fine with 2.3.9.RELEASE.

org.jooq.exception.DataTypeException: No Converter found for types MyBaseType and MyInheritType1 at 
org.jooq.impl.Tools.converterOrFail(Tools.java:1132) at      
org.jooq.impl.Tools.converterOrFail(Tools.java:1148) at 
org.jooq.impl.AbstractRecord.get(AbstractRecord.java:270) at 
org.jooq.impl.AbstractResultQuery.fetchOne(AbstractResultQuery.java:576) at 
org.jooq.impl.SelectImpl.fetchOne(SelectImpl.java:3019)

MyInheritType1 extends MyBaseType. The classes are using lombok @Data, so they should have the proper setters.

@Data
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "_class")
@JsonSubTypes(
        {
                @JsonSubTypes.Type(value = MyInheritType1.class, name = "Type1"),
                @JsonSubTypes.Type(value = MyInheritType2.class, name = "Type2")
        })
public class MyBaseType 
{
    private UUID id;
    private String disclaimerLongText = "";
    private LocalDateTime creationTime;
    private Map<UUID, String> images = new HashMap<>();
}

The inherited type:

@Data
public class MyInheritType1 extends MyBaseType 
{
    private String baseMap;
    private EnumType someEnum;
    private List<LayerType> layerTypes = new ArrayList<>();
    private double[] center;
}

I retrieve the data like this:

return dsl.select(PROJECT.DETAILS).from(PROJECT)
                .where(PROJECT.ID.eq(id.toString()))
                .fetchOne(PROJECT.DETAILS, MyInheritType1.class);

PROJECT.DETAILS is defined as this:

public final TableField<ProjectRecord, ProjectDetails> DETAILS = createField(DSL.name("details"), SQLDataType.JSONB.nullable(false), this, "", new ProjectDetailsBinding());

And ProjectDetailsBinding looks like this:

public class ProjectDetailsBinding extends JsonBBinding<MyBaseType>
{
    @Override
    protected Class<ProjectDetails> getBindingType()
    {
        return MyBaseType.class;
    }
}

public abstract class JsonBBinding<T> implements Binding<JSONB, T>
{
    private ObjectMapper objectMapper = new ObjectMapper()
            .registerModule(new JavaTimeModule());

    protected abstract Class<T> getBindingType();

    @Override
    public Converter<JSONB, T> converter()
    {
        return new Converter<JSONB, T>()
        {
            @Override
            public T from(JSONB o)
            {
                if (o == null)
                    return null;
                try
                {
                    return objectMapper.readValue(o.data(), getBindingType());
                } catch (Exception e)
                {
                    e.printStackTrace();
                }
                return null;
            }

            @Override
            public JSONB to(T t)
            {
                try
                {
                    return JSONB.valueOf(objectMapper.writeValueAsString(t));
                } catch (JsonProcessingException e)
                {
                    e.printStackTrace();
                }
                return null;
            }

            @Override
            public Class<JSONB> fromType()
            {
                return JSONB.class;
            }

            @Override
            public Class<T> toType()
            {
                return getBindingType();
            }
        };
    }
    [..]
}

Since it worked with 2.3.9.RELEASE, I am wondering what changed in Spring Boot or Jooq, that would cause this different behavior now?


Solution

  • Looks like https://github.com/jOOQ/jOOQ/issues/11762, fixed for 3.15.0 and 3.14.9, to be released soon. You can try building 3.14.9 from github or use a snapshot build from here: https://www.jooq.org/download/versions if you're licensed, to see if that fixes your issue.

    Alternatively, you can try to use the fixed version of the DefaultConverterProvider and use that in your Configuration.

    Since it worked with 2.3.9.RELEASE, I am wondering what changed in Spring Boot or Jooq, that would cause this different behavior now?

    Typically, Spring Boot upgrades come with jOOQ upgrades. You could also downgrade your jOOQ dependency to what you were using before with Spring Boot 2.3.9