如果Class0
属性具有静态类型unit
Unit
public class Class0 {
private Unit<?> unit;
[0-arg constructor, getter and setter]
}
与
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new UnitJacksonModule());
Class0 value = new Class0((AbstractUnit) SQUARE_METRE);
String json = objectMapper.writeValueAsString(value);
Class0 deserialized = objectMapper.readValue(json, Class0.class);
assertEquals(value, deserialized);
但是,我希望unit
拥有静态类型tec.uom.se.AbstractUnit
,因为它是Serializable
,这对JPA @Basic
持久性很重要,但由于}而失败p>
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `tec.uom.se.AbstractUnit` (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
at [Source: (String)"{"unit":"m2"}"; line: 1, column: 9] (through reference chain: de.richtercloud.jackson.unit.serialization.Class0["unit"])
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1451)
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1027)
at com.fasterxml.jackson.databind.deser.AbstractDeserializer.deserialize(AbstractDeserializer.java:265)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:127)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2992)
at de.richtercloud.jackson.unit.serialization.TheTest.testSerializationAndDeserialization(TheTest.java:30)
[some more irrelevant lines]
使用ObjectMapper.enableDefaultTyping
启用默认输入会导致序列化在因{/ 1}}从Unit
更改为AbstractUnit
之前已失败
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot find a (Map) Key deserializer for type [simple type, class javax.measure.Unit<java.lang.Object>]
at [Source: (String)"{"unit":["tec.uom.se.unit.ProductUnit","m2"]}"; line: 1, column: 40] (through reference chain: de.richtercloud.jackson.unit.serialization.Class0["unit"])
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1451)
at com.fasterxml.jackson.databind.deser.DeserializerCache._handleUnknownKeyDeserializer(DeserializerCache.java:599)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findKeyDeserializer(DeserializerCache.java:168)
at com.fasterxml.jackson.databind.DeserializationContext.findKeyDeserializer(DeserializationContext.java:500)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.createContextual(MapDeserializer.java:248)
at com.fasterxml.jackson.databind.DeserializationContext.handlePrimaryContextualization(DeserializationContext.java:651)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.resolve(BeanDeserializerBase.java:484)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:293)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
at com.fasterxml.jackson.databind.DeserializationContext.findContextualValueDeserializer(DeserializationContext.java:444)
at com.fasterxml.jackson.databind.jsontype.impl.TypeDeserializerBase._findDeserializer(TypeDeserializerBase.java:194)
at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer._deserialize(AsArrayTypeDeserializer.java:97)
at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer.deserializeTypedFromScalar(AsArrayTypeDeserializer.java:66)
at com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer.deserializeWithType(StdScalarDeserializer.java:26)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2992)
at de.richtercloud.jackson.unit.serialization.TheTest.testSerializationAndDeserialization(TheTest.java:30)
[some more irrelevant lines]
我显然不能注释Unit
声明它是序列化支持的子类型,因为它是作为依赖项传递的第三方接口。
使用
@JsonSerialize(as = Unit.class)
@JsonDeserialize(as = Unit.class)
private AbstractUnit<?> unit;
原因
com.fasterxml.jackson.databind.JsonMappingException: Failed to narrow type [simple type, class tec.uom.se.AbstractUnit<java.lang.Object>] with annotation (value javax.measure.Unit), from 'setUnit': Class javax.measure.Unit not subtype of [simple type, class tec.uom.se.AbstractUnit<java.lang.Object>]
at com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector.refineDeserializationType(JacksonAnnotationIntrospector.java:1130)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.resolveMemberAndTypeAnnotations(BasicDeserializerFactory.java:2082)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.constructSettableProperty(BeanDeserializerFactory.java:791)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.addBeanProps(BeanDeserializerFactory.java:514)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:227)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:137)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:411)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:349)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:477)
at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:4178)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3997)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2992)
at de.richtercloud.jackson.unit.serialization.TheTest.testSerializationAndDeserialization(TheTest.java:30)
我知道几乎所有的Unit
都是AbstractUnit
,因此Serializable
,但是我想要正确地做到这一点。我正在寻找一个纯粹的JPA解决方案,即不是特定于实现的解决方案,比如在Hibernate运行时检查的接口子类型的规范。
我正在使用
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.4</version>
</dependency>
<dependency>
<groupId>tec.uom</groupId>
<artifactId>uom-se</artifactId>
<version>1.0.8</version>
</dependency>
<dependency>
<groupId>com.opower.unitsofmeasure</groupId>
<artifactId>jackson-module-unitsofmeasure</artifactId>
<version>1.3.5-SNAPSHOT</version>
</dependency>