mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#1444 - JSON parsing with inheritance - java.lang.UnsupportedOperationException: cannot create entity bean for abstract entity ...
This commit is contained in:
@@ -291,6 +291,8 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
|
||||
*/
|
||||
protected final InheritInfo inheritInfo;
|
||||
|
||||
private final boolean abstractType;
|
||||
|
||||
/**
|
||||
* Derived list of properties that make up the unique id.
|
||||
*/
|
||||
@@ -546,7 +548,8 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
|
||||
this.whenCreatedProperty = findWhenCreatedProperty();
|
||||
|
||||
// derive the index position of the Id and Version properties
|
||||
if (Modifier.isAbstract(beanType.getModifiers())) {
|
||||
this.abstractType = Modifier.isAbstract(beanType.getModifiers());
|
||||
if (abstractType) {
|
||||
this.idPropertyIndex = -1;
|
||||
this.versionPropertyIndex = -1;
|
||||
this.unloadProperties = new int[0];
|
||||
@@ -653,6 +656,13 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
|
||||
return ebeanServer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this is an abstract type.
|
||||
*/
|
||||
public boolean isAbstractType() {
|
||||
return abstractType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this is a "Doc Store only" entity bean.
|
||||
*/
|
||||
@@ -3433,11 +3443,11 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
|
||||
}
|
||||
|
||||
public T jsonRead(SpiJsonReader jsonRead, String path) throws IOException {
|
||||
return jsonHelp.jsonRead(jsonRead, path);
|
||||
return jsonHelp.jsonRead(jsonRead, path, true);
|
||||
}
|
||||
|
||||
protected T jsonReadObject(SpiJsonReader jsonRead, String path) throws IOException {
|
||||
return jsonHelp.jsonReadObject(jsonRead, path);
|
||||
public T jsonReadObject(SpiJsonReader jsonRead, String path) throws IOException {
|
||||
return jsonHelp.jsonRead(jsonRead, path, false);
|
||||
}
|
||||
|
||||
public List<BeanProperty[]> getUniqueProps() {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -151,7 +151,6 @@ public class InheritInfo {
|
||||
* Set the descriptor for this node.
|
||||
*/
|
||||
public void setDescriptor(BeanDescriptor<?> descriptor) {
|
||||
|
||||
this.descriptor = descriptor;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.ebeaninternal.server.deploy.meta;
|
||||
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptorMap;
|
||||
import io.ebeaninternal.server.deploy.BeanProperty;
|
||||
@@ -11,6 +12,7 @@ import io.ebeaninternal.server.deploy.BeanPropertySimpleCollection;
|
||||
import io.ebeaninternal.server.deploy.InheritInfo;
|
||||
import io.ebeaninternal.server.deploy.TableJoin;
|
||||
import io.ebeaninternal.server.deploy.generatedproperty.GeneratedProperty;
|
||||
import io.ebeaninternal.server.properties.BeanPropertySetter;
|
||||
import io.ebeaninternal.server.type.ScalarTypeString;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -26,6 +28,8 @@ public class DeployBeanPropertyLists {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DeployBeanPropertyLists.class);
|
||||
|
||||
private static final NoopSetter NOOP_SETTER = new NoopSetter();
|
||||
|
||||
private BeanProperty versionProperty;
|
||||
|
||||
private BeanProperty unmappedJson;
|
||||
@@ -100,6 +104,7 @@ public class DeployBeanPropertyLists {
|
||||
discDeployProp.setDiscriminator();
|
||||
discDeployProp.setName(discriminatorColumn);
|
||||
discDeployProp.setDbColumn(discriminatorColumn);
|
||||
discDeployProp.setSetter(NOOP_SETTER);
|
||||
|
||||
// only register it in the propertyMap. This might not be used if
|
||||
// an explicit property is mapped to the discriminator on the bean
|
||||
@@ -491,4 +496,17 @@ public class DeployBeanPropertyLists {
|
||||
|
||||
return new BeanProperty(desc, deployProp);
|
||||
}
|
||||
|
||||
private static class NoopSetter implements BeanPropertySetter {
|
||||
|
||||
@Override
|
||||
public void set(EntityBean bean, Object value) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIntercept(EntityBean bean, Object value) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user