Jooq DataTypeException 自 Spring.Boot 2.4.x
Jooq DataTypeException since Spring.Boot 2.4.x
自升级到 Spring Boot 2.4.x 以来,我在检索数据时收到 DataTypeException。它适用于 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 扩展了 MyBaseType。
类 使用的是 lombok @Data,所以它们应该有合适的 setter。
@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<>();
}
继承类型:
@Data
public class MyInheritType1 extends MyBaseType
{
private String baseMap;
private EnumType someEnum;
private List<LayerType> layerTypes = new ArrayList<>();
private double[] center;
}
我这样检索数据:
return dsl.select(PROJECT.DETAILS).from(PROJECT)
.where(PROJECT.ID.eq(id.toString()))
.fetchOne(PROJECT.DETAILS, MyInheritType1.class);
PROJECT.DETAILS 定义为:
public final TableField<ProjectRecord, ProjectDetails> DETAILS = createField(DSL.name("details"), SQLDataType.JSONB.nullable(false), this, "", new ProjectDetailsBinding());
ProjectDetailsBinding 如下所示:
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();
}
};
}
[..]
}
因为它适用于 2.3.9.RELEASE,我想知道 Spring Boot 或 Jooq 中发生了什么变化,现在会导致这种不同的行为吗?
看起来 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 如果您已获得许可,请查看是否可以解决您的问题。
或者,您可以尝试使用 the fixed version of the DefaultConverterProvider
并在您的 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?
通常,Spring 引导升级伴随 jOOQ 升级。你也可以将你的 jOOQ 依赖降级到你之前使用的 Spring Boot 2.3.9
自升级到 Spring Boot 2.4.x 以来,我在检索数据时收到 DataTypeException。它适用于 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 扩展了 MyBaseType。 类 使用的是 lombok @Data,所以它们应该有合适的 setter。
@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<>();
}
继承类型:
@Data
public class MyInheritType1 extends MyBaseType
{
private String baseMap;
private EnumType someEnum;
private List<LayerType> layerTypes = new ArrayList<>();
private double[] center;
}
我这样检索数据:
return dsl.select(PROJECT.DETAILS).from(PROJECT)
.where(PROJECT.ID.eq(id.toString()))
.fetchOne(PROJECT.DETAILS, MyInheritType1.class);
PROJECT.DETAILS 定义为:
public final TableField<ProjectRecord, ProjectDetails> DETAILS = createField(DSL.name("details"), SQLDataType.JSONB.nullable(false), this, "", new ProjectDetailsBinding());
ProjectDetailsBinding 如下所示:
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();
}
};
}
[..]
}
因为它适用于 2.3.9.RELEASE,我想知道 Spring Boot 或 Jooq 中发生了什么变化,现在会导致这种不同的行为吗?
看起来 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 如果您已获得许可,请查看是否可以解决您的问题。
或者,您可以尝试使用 the fixed version of the DefaultConverterProvider
并在您的 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?
通常,Spring 引导升级伴随 jOOQ 升级。你也可以将你的 jOOQ 依赖降级到你之前使用的 Spring Boot 2.3.9