#1444 - JSON parsing with inheritance - java.lang.UnsupportedOperationException: cannot create entity bean for abstract entity ...

This commit is contained in:
rob bygrave
2018-07-04 21:26:17 +12:00
parent 1ba9f4e9de
commit c981944c8e
5 changed files with 71 additions and 37 deletions
@@ -3,6 +3,8 @@ package io.ebeaninternal.server.deploy;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.ebean.bean.EntityBean;
import io.ebean.text.json.EJson;
import io.ebeaninternal.api.json.SpiJsonReader;
@@ -12,18 +14,18 @@ import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
public class BeanDescriptorJsonHelp<T> {
class BeanDescriptorJsonHelp<T> {
private final BeanDescriptor<T> desc;
private final InheritInfo inheritInfo;
public BeanDescriptorJsonHelp(BeanDescriptor<T> desc) {
BeanDescriptorJsonHelp(BeanDescriptor<T> desc) {
this.desc = desc;
this.inheritInfo = desc.inheritInfo;
}
public void jsonWrite(SpiJsonWriter writeJson, EntityBean bean, String key) throws IOException {
void jsonWrite(SpiJsonWriter writeJson, EntityBean bean, String key) throws IOException {
writeJson.writeStartObject(key);
@@ -42,13 +44,11 @@ public class BeanDescriptorJsonHelp<T> {
writeJson.writeEndObject();
}
protected void jsonWriteProperties(SpiJsonWriter writeJson, EntityBean bean) throws IOException {
void jsonWriteProperties(SpiJsonWriter writeJson, EntityBean bean) {
writeJson.writeBean(desc, bean);
}
public void jsonWriteDirty(SpiJsonWriter writeJson, EntityBean bean, boolean[] dirtyProps) throws IOException {
void jsonWriteDirty(SpiJsonWriter writeJson, EntityBean bean, boolean[] dirtyProps) throws IOException {
if (inheritInfo == null) {
jsonWriteDirtyProperties(writeJson, bean, dirtyProps);
} else {
@@ -56,7 +56,7 @@ public class BeanDescriptorJsonHelp<T> {
}
}
protected void jsonWriteDirtyProperties(SpiJsonWriter writeJson, EntityBean bean, boolean[] dirtyProps) throws IOException {
void jsonWriteDirtyProperties(SpiJsonWriter writeJson, EntityBean bean, boolean[] dirtyProps) throws IOException {
writeJson.writeStartObject(null);
// render the dirty properties
@@ -70,7 +70,7 @@ public class BeanDescriptorJsonHelp<T> {
}
@SuppressWarnings("unchecked")
public T jsonRead(SpiJsonReader jsonRead, String path) throws IOException {
T jsonRead(SpiJsonReader jsonRead, String path, boolean withInheritance) throws IOException {
JsonParser parser = jsonRead.getParser();
//noinspection StatementWithEmptyBody
@@ -87,43 +87,39 @@ public class BeanDescriptorJsonHelp<T> {
}
}
if (desc.inheritInfo == null) {
if (desc.inheritInfo == null || !withInheritance) {
return jsonReadObject(jsonRead, path);
}
ObjectNode node = jsonRead.getObjectMapper().readTree(parser);
if (node.isNull()) {
return null;
}
JsonParser newParser = node.traverse();
SpiJsonReader newReader = jsonRead.forJson(newParser, false);
// check for the discriminator value to determine the correct sub type
String discColumn = inheritInfo.getRoot().getDiscriminatorColumn();
if (parser.nextToken() != JsonToken.FIELD_NAME) {
String msg = "Error reading inheritance discriminator - expected [" + discColumn + "] but no json key?";
throw new JsonParseException(parser, msg, parser.getCurrentLocation());
}
String propName = parser.getCurrentName();
if (!propName.equalsIgnoreCase(discColumn)) {
// just try to assume this is the correct bean type in the inheritance
BeanProperty property = desc.getBeanProperty(propName);
if (property != null) {
EntityBean bean = desc.createEntityBean();
property.jsonRead(jsonRead, bean);
return jsonReadProperties(jsonRead, bean, path);
JsonNode discNode = node.get(discColumn);
if (discNode == null || discNode.isNull()) {
if (!desc.isAbstractType()) {
return desc.jsonReadObject(newReader, path);
}
String msg = "Error reading inheritance discriminator, expected property [" + discColumn + "] but got [" + propName + "] ?";
throw new JsonParseException(parser, msg, parser.getCurrentLocation());
String msg = "Error reading inheritance discriminator - expected [" + discColumn + "] but no json key?";
throw new JsonParseException(newParser, msg, parser.getCurrentLocation());
}
String discValue = parser.nextTextValue();
return (T) inheritInfo.readType(discValue).desc().jsonReadObject(jsonRead, path);
return (T) inheritInfo.readType(discNode.asText()).desc().jsonReadObject(newReader, path);
}
protected T jsonReadObject(SpiJsonReader readJson, String path) throws IOException {
private T jsonReadObject(SpiJsonReader readJson, String path) throws IOException {
EntityBean bean = desc.createEntityBeanForJson();
return jsonReadProperties(readJson, bean, path);
}
@SuppressWarnings("unchecked")
protected T jsonReadProperties(SpiJsonReader readJson, EntityBean bean, String path) throws IOException {
private T jsonReadProperties(SpiJsonReader readJson, EntityBean bean, String path) throws IOException {
if (path != null) {
readJson.pushPath(path);