mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#115 - Mapping - Add support for @ElementCollection enhancement
Add element collection L2 cache support
This commit is contained in:
@@ -63,7 +63,7 @@ abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
|
||||
this.ebeanServerName = loader.getName();
|
||||
this.ownerBean = ownerBean;
|
||||
this.propertyName = propertyName;
|
||||
this.readOnly = ownerBean._ebean_getIntercept().isReadOnly();
|
||||
this.readOnly = ownerBean != null && ownerBean._ebean_getIntercept().isReadOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package io.ebeaninternal.api;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import io.ebean.plugin.BeanType;
|
||||
import io.ebean.text.json.JsonContext;
|
||||
import io.ebean.text.json.JsonWriteOptions;
|
||||
import io.ebeaninternal.server.text.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.api.json.SpiJsonReader;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
|
||||
import java.io.Writer;
|
||||
|
||||
@@ -21,4 +23,10 @@ public interface SpiJsonContext extends JsonContext {
|
||||
* Create a Json Writer for writing beans as JSON supplying a writer.
|
||||
*/
|
||||
SpiJsonWriter createJsonWriter(Writer writer);
|
||||
|
||||
/**
|
||||
* Create a Json Reader for reading the JSON content.
|
||||
*/
|
||||
SpiJsonReader createJsonRead(BeanType<?> beanType, String json);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package io.ebeaninternal.api.json;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.bean.PersistenceContext;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
public interface SpiJsonReader {
|
||||
|
||||
PersistenceContext getPersistenceContext();
|
||||
|
||||
SpiJsonReader forJson(JsonParser moreJson, boolean resetContext);
|
||||
|
||||
<T> void persistenceContextPut(Object beanId, T currentBean);
|
||||
|
||||
Object persistenceContextPutIfAbsent(Object id, EntityBean bean, BeanDescriptor<?> beanDesc);
|
||||
|
||||
ObjectMapper getObjectMapper();
|
||||
|
||||
JsonParser getParser();
|
||||
|
||||
JsonToken nextToken() throws IOException;
|
||||
|
||||
void pushPath(String path);
|
||||
|
||||
void popPath();
|
||||
|
||||
void beanVisitor(Object bean, Map<String, Object> unmappedProperties);
|
||||
|
||||
Object readValueUsingObjectMapper(Class<?> propertyType) throws IOException;
|
||||
}
|
||||
+8
-2
@@ -1,9 +1,10 @@
|
||||
package io.ebeaninternal.server.text.json;
|
||||
package io.ebeaninternal.api.json;
|
||||
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.text.json.JsonWriter;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
@@ -11,6 +12,11 @@ import java.util.Collection;
|
||||
*/
|
||||
public interface SpiJsonWriter extends JsonWriter {
|
||||
|
||||
/**
|
||||
* Flush the buffer.
|
||||
*/
|
||||
void flush() throws IOException;
|
||||
|
||||
/**
|
||||
* Return true if the value is a parent bean.
|
||||
*/
|
||||
@@ -60,7 +66,7 @@ public interface SpiJsonWriter extends JsonWriter {
|
||||
* Write value using underlying Jaskson object mapper if available.
|
||||
*/
|
||||
void writeValueUsingObjectMapper(String name, Object value);
|
||||
|
||||
|
||||
/**
|
||||
* Write the bean properties.
|
||||
*/
|
||||
@@ -4,6 +4,7 @@ import io.ebean.bean.EntityBean;
|
||||
import io.ebean.bean.EntityBeanIntercept;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.deploy.BeanProperty;
|
||||
import io.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
@@ -33,6 +34,12 @@ public class CachedBeanDataFromBean {
|
||||
}
|
||||
}
|
||||
|
||||
for (BeanPropertyAssocMany<?> prop : desc.propertiesMany()) {
|
||||
if (prop.isElementCollection()) {
|
||||
data.put(prop.getName(), prop.getCacheDataValue(bean));
|
||||
}
|
||||
}
|
||||
|
||||
long version = desc.getVersion(bean);
|
||||
EntityBean sharableBean = createSharableBean(desc, bean, ebi);
|
||||
return new CachedBeanData(sharableBean, desc.getDiscValue(), data, version);
|
||||
|
||||
@@ -21,14 +21,16 @@ public class CachedBeanDataToBean {
|
||||
}
|
||||
|
||||
// load the non-many properties
|
||||
BeanProperty[] props = desc.propertiesNonMany();
|
||||
for (BeanProperty prop : props) {
|
||||
for (BeanProperty prop : desc.propertiesNonMany()) {
|
||||
loadProperty(bean, cacheBeanData, ebi, prop, context);
|
||||
}
|
||||
|
||||
BeanPropertyAssocMany<?>[] many = desc.propertiesMany();
|
||||
for (BeanPropertyAssocMany<?> aMany : many) {
|
||||
aMany.createReferenceIfNull(bean);
|
||||
for (BeanPropertyAssocMany<?> prop : desc.propertiesMany()) {
|
||||
if (prop.isElementCollection()) {
|
||||
loadProperty(bean, cacheBeanData, ebi, prop, context);
|
||||
} else {
|
||||
prop.createReferenceIfNull(bean);
|
||||
}
|
||||
}
|
||||
|
||||
ebi.setLoadedLazy();
|
||||
|
||||
@@ -35,6 +35,7 @@ import javax.persistence.PersistenceException;
|
||||
import java.io.IOException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -107,6 +108,11 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
*/
|
||||
private boolean updatedManysOnly;
|
||||
|
||||
/**
|
||||
* Element collection change as part of bean cache.
|
||||
*/
|
||||
private Map<String, Object> collectionChanges;
|
||||
|
||||
/**
|
||||
* Many properties that were cascade saved (and hence might need caches updated later).
|
||||
*/
|
||||
@@ -938,10 +944,14 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
/**
|
||||
* Combine with the beans postUpdate event notification.
|
||||
*/
|
||||
public void postElementCollectionUpdate() {
|
||||
public boolean postElementCollectionUpdate() {
|
||||
if (controller != null) {
|
||||
pendingPostUpdateNotify += 2;
|
||||
}
|
||||
if (!dirty) {
|
||||
setNotifyCache();
|
||||
}
|
||||
return notifyCache;
|
||||
}
|
||||
|
||||
private void controllerPost() {
|
||||
@@ -1079,13 +1089,6 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
postUpdateNotify();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if only many properties where updated.
|
||||
*/
|
||||
public boolean isUpdatedManysOnly() {
|
||||
return updatedManysOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* For requests that update document store add this event to either the list
|
||||
* of queue events or list of update events.
|
||||
@@ -1311,4 +1314,50 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
public boolean isInsertedParent() {
|
||||
return Flags.isInsert(flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an element collection change to L2 bean cache update.
|
||||
*/
|
||||
public void addCollectionChange(String name, Object value) {
|
||||
if (collectionChanges == null) {
|
||||
collectionChanges = new LinkedHashMap<>();
|
||||
}
|
||||
collectionChanges.put(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the bean update for the L2 cache.
|
||||
*/
|
||||
public void addBeanUpdate(CacheChangeSet changeSet) {
|
||||
|
||||
if (!updatedManysOnly || collectionChanges != null) {
|
||||
|
||||
boolean updateNaturalKey = false;
|
||||
|
||||
Map<String, Object> changes = new LinkedHashMap<>();
|
||||
EntityBean bean = getEntityBean();
|
||||
boolean[] dirtyProperties = getDirtyProperties();
|
||||
if (dirtyProperties != null) {
|
||||
for (int i = 0; i < dirtyProperties.length; i++) {
|
||||
if (dirtyProperties[i]) {
|
||||
BeanProperty property = beanDescriptor.propertyByIndex(i);
|
||||
if (property.isCacheDataInclude()) {
|
||||
Object val = property.getCacheDataValue(bean);
|
||||
changes.put(property.getName(), val);
|
||||
if (property.isNaturalKey()) {
|
||||
updateNaturalKey = true;
|
||||
changeSet.addNaturalKeyPut(beanDescriptor, idValue, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (collectionChanges != null) {
|
||||
// add element collection update
|
||||
changes.putAll(collectionChanges);
|
||||
}
|
||||
|
||||
changeSet.addBeanUpdate(beanDescriptor, idValue, changes, updateNaturalKey, getVersion());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package io.ebeaninternal.server.deploy;
|
||||
import io.ebean.bean.BeanCollection;
|
||||
import io.ebean.bean.BeanCollectionLoader;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebeaninternal.server.text.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
@@ -2,7 +2,7 @@ package io.ebeaninternal.server.deploy;
|
||||
|
||||
import io.ebean.PersistenceIOException;
|
||||
import io.ebean.bean.BeanDiffVisitor;
|
||||
import io.ebeaninternal.server.text.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.server.util.ArrayStack;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -82,10 +82,10 @@ class BeanChangeJson implements BeanDiffVisitor {
|
||||
void flush() {
|
||||
try {
|
||||
newJson.writeEndObject();
|
||||
newJson.gen().flush();
|
||||
newJson.flush();
|
||||
if (oldJson != null) {
|
||||
oldJson.writeEndObject();
|
||||
oldJson.gen().flush();
|
||||
oldJson.flush();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new PersistenceIOException(e);
|
||||
|
||||
@@ -7,8 +7,8 @@ import io.ebean.bean.BeanCollection;
|
||||
import io.ebean.bean.BeanCollectionAdd;
|
||||
import io.ebean.bean.BeanCollectionLoader;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.server.query.CQueryCollectionAdd;
|
||||
import io.ebeaninternal.server.text.json.SpiJsonWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
@@ -41,6 +41,8 @@ import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.api.SpiUpdatePlan;
|
||||
import io.ebeaninternal.api.TransactionEventTable.TableIUD;
|
||||
import io.ebeaninternal.api.json.SpiJsonReader;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.server.cache.CacheChangeSet;
|
||||
import io.ebeaninternal.server.cache.CachedBeanData;
|
||||
import io.ebeaninternal.server.cache.CachedManyIds;
|
||||
@@ -71,8 +73,6 @@ import io.ebeaninternal.server.query.STreeType;
|
||||
import io.ebeaninternal.server.query.SqlBeanLoad;
|
||||
import io.ebeaninternal.server.querydefn.OrmQueryDetail;
|
||||
import io.ebeaninternal.server.rawsql.SpiRawSql;
|
||||
import io.ebeaninternal.server.text.json.ReadJson;
|
||||
import io.ebeaninternal.server.text.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.server.type.DataBind;
|
||||
import io.ebeaninternal.server.type.ScalarType;
|
||||
import io.ebeaninternal.util.SortByClause;
|
||||
@@ -662,6 +662,10 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public BeanProperty propertyByIndex(int pos) {
|
||||
return propertiesIndex[pos];
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the Id properties first.
|
||||
* <p>
|
||||
@@ -945,7 +949,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
|
||||
SpiJsonWriter jsonWriter = createJsonWriter(writer);
|
||||
|
||||
jsonWriteForInsert(jsonWriter, request.getEntityBean());
|
||||
jsonWriter.gen().flush();
|
||||
jsonWriter.flush();
|
||||
|
||||
return beanChange(ChangeType.INSERT, request.getBeanId(), writer.toString(), null);
|
||||
|
||||
@@ -959,6 +963,10 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
|
||||
return ebeanServer.jsonExtended().createJsonWriter(writer);
|
||||
}
|
||||
|
||||
SpiJsonReader createJsonReader(String json) {
|
||||
return ebeanServer.jsonExtended().createJsonRead(this, json);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate the diff for inserts with flattened non-null property values.
|
||||
*/
|
||||
@@ -3355,7 +3363,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
|
||||
throw new IllegalStateException("Unexpected - expect Element override");
|
||||
}
|
||||
|
||||
public Object jsonReadCollection(ReadJson readJson, EntityBean parentBean) throws IOException {
|
||||
public Object jsonReadCollection(SpiJsonReader readJson, EntityBean parentBean) throws IOException {
|
||||
throw new IllegalStateException("Unexpected - expect Element override");
|
||||
}
|
||||
|
||||
@@ -3371,11 +3379,11 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
|
||||
jsonHelp.jsonWriteProperties(writeJson, bean);
|
||||
}
|
||||
|
||||
public T jsonRead(ReadJson jsonRead, String path) throws IOException {
|
||||
public T jsonRead(SpiJsonReader jsonRead, String path) throws IOException {
|
||||
return jsonHelp.jsonRead(jsonRead, path);
|
||||
}
|
||||
|
||||
protected T jsonReadObject(ReadJson jsonRead, String path) throws IOException {
|
||||
protected T jsonReadObject(SpiJsonReader jsonRead, String path) throws IOException {
|
||||
return jsonHelp.jsonReadObject(jsonRead, path);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import io.ebeaninternal.server.transaction.DefaultPersistenceContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
@@ -272,6 +273,11 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
*/
|
||||
boolean manyPropLoad(BeanPropertyAssocMany<?> many, BeanCollection<?> bc, Object parentId, Boolean readOnly) {
|
||||
|
||||
if (many.isElementCollection()) {
|
||||
// held as part of the bean cache so skip
|
||||
return false;
|
||||
}
|
||||
|
||||
CachedManyIds entry = manyPropGet(parentId, many.getName());
|
||||
if (entry == null) {
|
||||
// not in cache so return unsuccessful
|
||||
@@ -298,9 +304,29 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
*/
|
||||
void manyPropPut(BeanPropertyAssocMany<?> many, Object details, Object parentId) {
|
||||
|
||||
CachedManyIds entry = createManyIds(many, details);
|
||||
if (entry != null) {
|
||||
cachePutManyIds(parentId, many.getName(), entry);
|
||||
if (many.isElementCollection()) {
|
||||
CachedBeanData data = (CachedBeanData) beanCache.get(parentId);
|
||||
if (data != null) {
|
||||
try {
|
||||
// add as JSON to bean cache
|
||||
String asJson = many.jsonWriteCollection(details);
|
||||
Map<String,Object> changes = new HashMap<>();
|
||||
changes.put(many.getName(), asJson);
|
||||
|
||||
CachedBeanData newData = data.update(changes, data.getVersion());
|
||||
if (beanLog.isDebugEnabled()) {
|
||||
beanLog.debug(" UPDATE {}({}) changes:{}", cacheName, parentId, changes);
|
||||
}
|
||||
beanCache.put(parentId, newData);
|
||||
} catch (IOException e) {
|
||||
logger.error("Error updating L2 cache", e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CachedManyIds entry = createManyIds(many, details);
|
||||
if (entry != null) {
|
||||
cachePutManyIds(parentId, many.getName(), entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -730,38 +756,17 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
List<BeanPropertyAssocMany<?>> manyCollections = updateRequest.getUpdatedManyCollections();
|
||||
if (manyCollections != null) {
|
||||
for (BeanPropertyAssocMany<?> many : manyCollections) {
|
||||
Object details = many.getValue(updateRequest.getEntityBean());
|
||||
CachedManyIds entry = createManyIds(many, details);
|
||||
if (entry != null) {
|
||||
changeSet.addManyPut(desc, many.getName(), id, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check if the bean itself was updated
|
||||
if (!updateRequest.isUpdatedManysOnly()) {
|
||||
|
||||
boolean updateNaturalKey = false;
|
||||
|
||||
Map<String, Object> changes = new LinkedHashMap<>();
|
||||
EntityBean bean = updateRequest.getEntityBean();
|
||||
boolean[] dirtyProperties = updateRequest.getDirtyProperties();
|
||||
for (int i = 0; i < dirtyProperties.length; i++) {
|
||||
if (dirtyProperties[i]) {
|
||||
BeanProperty property = desc.propertiesIndex[i];
|
||||
if (property.isCacheDataInclude()) {
|
||||
Object val = property.getCacheDataValue(bean);
|
||||
changes.put(property.getName(), val);
|
||||
if (property.isNaturalKey()) {
|
||||
updateNaturalKey = true;
|
||||
changeSet.addNaturalKeyPut(desc, id, val);
|
||||
}
|
||||
if (!many.isElementCollection()) {
|
||||
Object details = many.getValue(updateRequest.getEntityBean());
|
||||
CachedManyIds entry = createManyIds(many, details);
|
||||
if (entry != null) {
|
||||
changeSet.addManyPut(desc, many.getName(), id, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
changeSet.addBeanUpdate(desc, id, changes, updateNaturalKey, updateRequest.getVersion());
|
||||
}
|
||||
|
||||
updateRequest.addBeanUpdate(changeSet);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,9 +3,9 @@ package io.ebeaninternal.server.deploy;
|
||||
import io.ebean.PersistenceIOException;
|
||||
import io.ebean.SqlUpdate;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebeaninternal.api.json.SpiJsonReader;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.server.deploy.meta.DeployBeanDescriptor;
|
||||
import io.ebeaninternal.server.text.json.ReadJson;
|
||||
import io.ebeaninternal.server.text.json.SpiJsonWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -56,12 +56,12 @@ class BeanDescriptorElementEmbedded<T> extends BeanDescriptorElement<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public T jsonRead(ReadJson jsonRead, String path) throws IOException {
|
||||
public T jsonRead(SpiJsonReader jsonRead, String path) throws IOException {
|
||||
return readJsonElement(jsonRead, path);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
T readJsonElement(ReadJson jsonRead, String path) throws IOException {
|
||||
T readJsonElement(SpiJsonReader jsonRead, String path) throws IOException {
|
||||
return (T)targetDescriptor.jsonRead(jsonRead, path);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@ package io.ebeaninternal.server.deploy;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebeaninternal.api.json.SpiJsonReader;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.server.deploy.meta.DeployBeanDescriptor;
|
||||
import io.ebeaninternal.server.text.json.ReadJson;
|
||||
import io.ebeaninternal.server.text.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.server.type.ScalarType;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -47,7 +47,7 @@ class BeanDescriptorElementEmbeddedMap<T> extends BeanDescriptorElementEmbedded<
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonReadCollection(ReadJson readJson, EntityBean parentBean) throws IOException {
|
||||
public Object jsonReadCollection(SpiJsonReader readJson, EntityBean parentBean) throws IOException {
|
||||
|
||||
JsonParser parser = readJson.getParser();
|
||||
ElementCollector add = elementHelp.createCollector();
|
||||
|
||||
@@ -5,9 +5,9 @@ import com.fasterxml.jackson.core.JsonToken;
|
||||
import io.ebean.PersistenceIOException;
|
||||
import io.ebean.SqlUpdate;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebeaninternal.api.json.SpiJsonReader;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.server.deploy.meta.DeployBeanDescriptor;
|
||||
import io.ebeaninternal.server.text.json.ReadJson;
|
||||
import io.ebeaninternal.server.text.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.server.type.ScalarType;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -38,7 +38,7 @@ class BeanDescriptorElementScalar<T> extends BeanDescriptorElement<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonReadCollection(ReadJson readJson, EntityBean parentBean) throws IOException {
|
||||
public Object jsonReadCollection(SpiJsonReader readJson, EntityBean parentBean) throws IOException {
|
||||
|
||||
JsonParser parser = readJson.getParser();
|
||||
ElementCollector add = elementHelp.createCollector();
|
||||
|
||||
@@ -3,9 +3,9 @@ package io.ebeaninternal.server.deploy;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebeaninternal.api.json.SpiJsonReader;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.server.deploy.meta.DeployBeanDescriptor;
|
||||
import io.ebeaninternal.server.text.json.ReadJson;
|
||||
import io.ebeaninternal.server.text.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.server.type.ScalarType;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -51,7 +51,7 @@ class BeanDescriptorElementScalarMap<T> extends BeanDescriptorElement<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonReadCollection(ReadJson readJson, EntityBean parentBean) throws IOException {
|
||||
public Object jsonReadCollection(SpiJsonReader readJson, EntityBean parentBean) throws IOException {
|
||||
|
||||
JsonParser parser = readJson.getParser();
|
||||
ElementCollector add = elementHelp.createCollector();
|
||||
|
||||
@@ -5,8 +5,8 @@ import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.text.json.EJson;
|
||||
import io.ebeaninternal.server.text.json.ReadJson;
|
||||
import io.ebeaninternal.server.text.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.api.json.SpiJsonReader;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -70,7 +70,7 @@ public class BeanDescriptorJsonHelp<T> {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public T jsonRead(ReadJson jsonRead, String path) throws IOException {
|
||||
public T jsonRead(SpiJsonReader jsonRead, String path) throws IOException {
|
||||
|
||||
JsonParser parser = jsonRead.getParser();
|
||||
//noinspection StatementWithEmptyBody
|
||||
@@ -116,14 +116,14 @@ public class BeanDescriptorJsonHelp<T> {
|
||||
return (T) inheritInfo.readType(discValue).desc().jsonReadObject(jsonRead, path);
|
||||
}
|
||||
|
||||
protected T jsonReadObject(ReadJson readJson, String path) throws IOException {
|
||||
protected T jsonReadObject(SpiJsonReader readJson, String path) throws IOException {
|
||||
|
||||
EntityBean bean = desc.createEntityBeanForJson();
|
||||
return jsonReadProperties(readJson, bean, path);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected T jsonReadProperties(ReadJson readJson, EntityBean bean, String path) throws IOException {
|
||||
protected T jsonReadProperties(SpiJsonReader readJson, EntityBean bean, String path) throws IOException {
|
||||
|
||||
if (path != null) {
|
||||
readJson.pushPath(path);
|
||||
|
||||
@@ -7,7 +7,7 @@ import io.ebean.bean.BeanCollection;
|
||||
import io.ebean.bean.BeanCollectionAdd;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.common.BeanList;
|
||||
import io.ebeaninternal.server.text.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -2,7 +2,7 @@ package io.ebeaninternal.server.deploy;
|
||||
|
||||
import io.ebean.bean.BeanCollection;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebeaninternal.server.text.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
|
||||
/**
|
||||
* Helper for element collection List.
|
||||
|
||||
@@ -7,7 +7,7 @@ import io.ebean.bean.BeanCollection;
|
||||
import io.ebean.bean.BeanCollectionAdd;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.common.BeanMap;
|
||||
import io.ebeaninternal.server.text.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
@@ -3,7 +3,7 @@ package io.ebeaninternal.server.deploy;
|
||||
import io.ebean.bean.BeanCollection;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.common.BeanMap;
|
||||
import io.ebeaninternal.server.text.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
|
||||
public class BeanMapHelpElement<T> extends BeanMapHelp<T> {
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ import io.ebean.util.SplitName;
|
||||
import io.ebean.util.StringHelper;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.api.json.SpiJsonReader;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.server.core.InternString;
|
||||
import io.ebeaninternal.server.deploy.generatedproperty.GeneratedProperty;
|
||||
import io.ebeaninternal.server.deploy.generatedproperty.GeneratedWhenCreated;
|
||||
@@ -25,8 +27,6 @@ import io.ebeaninternal.server.properties.BeanPropertySetter;
|
||||
import io.ebeaninternal.server.query.STreeProperty;
|
||||
import io.ebeaninternal.server.query.SqlBeanLoad;
|
||||
import io.ebeaninternal.server.query.SqlJoinType;
|
||||
import io.ebeaninternal.server.text.json.ReadJson;
|
||||
import io.ebeaninternal.server.text.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.server.type.DataBind;
|
||||
import io.ebeaninternal.server.type.ScalarType;
|
||||
import io.ebeaninternal.server.type.ScalarTypeBoolean;
|
||||
@@ -1453,7 +1453,7 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
|
||||
}
|
||||
}
|
||||
|
||||
public void jsonRead(ReadJson ctx, EntityBean bean) throws IOException {
|
||||
public void jsonRead(SpiJsonReader ctx, EntityBean bean) throws IOException {
|
||||
|
||||
JsonToken event = ctx.nextToken();
|
||||
if (JsonToken.VALUE_NULL == event) {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package io.ebeaninternal.server.deploy;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import io.ebean.SqlUpdate;
|
||||
import io.ebean.Transaction;
|
||||
import io.ebean.bean.BeanCollection;
|
||||
@@ -7,22 +9,24 @@ import io.ebean.bean.BeanCollection.ModifyListenMode;
|
||||
import io.ebean.bean.BeanCollectionAdd;
|
||||
import io.ebean.bean.BeanCollectionLoader;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.bean.PersistenceContext;
|
||||
import io.ebean.text.PathProperties;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.api.json.SpiJsonReader;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.server.deploy.id.ImportedId;
|
||||
import io.ebeaninternal.server.deploy.meta.DeployBeanPropertyAssocMany;
|
||||
import io.ebeaninternal.server.el.ElPropertyChainBuilder;
|
||||
import io.ebeaninternal.server.el.ElPropertyValue;
|
||||
import io.ebeaninternal.server.query.STreePropertyAssocMany;
|
||||
import io.ebeaninternal.server.query.SqlBeanLoad;
|
||||
import io.ebeaninternal.server.text.json.ReadJson;
|
||||
import io.ebeaninternal.server.text.json.SpiJsonWriter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -804,7 +808,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
||||
if (value != null) {
|
||||
ctx.pushParentBeanMany(bean);
|
||||
if (help != null) {
|
||||
help.jsonWrite(ctx, name, value, include != null);
|
||||
jsonWriteCollection(ctx, name, value, include != null);
|
||||
} else {
|
||||
if (isTransient && targetDescriptor == null) {
|
||||
ctx.writeValueUsingObjectMapper(name, value);
|
||||
@@ -820,7 +824,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonRead(ReadJson readJson, EntityBean parentBean) throws IOException {
|
||||
public void jsonRead(SpiJsonReader readJson, EntityBean parentBean) throws IOException {
|
||||
jsonHelp.jsonRead(readJson, parentBean);
|
||||
}
|
||||
|
||||
@@ -909,10 +913,69 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
||||
elementDescriptor.jsonWriteElement(ctx, element);
|
||||
}
|
||||
|
||||
/**
|
||||
* A Many (element collection) property in bean cache to held as JSON.
|
||||
*/
|
||||
@Override
|
||||
public void setCacheDataValue(EntityBean bean, Object cacheData, PersistenceContext context) {
|
||||
try {
|
||||
String asJson = (String) cacheData;
|
||||
Object collection = jsonReadCollection(asJson);
|
||||
setValue(bean, collection);
|
||||
} catch (Exception e) {
|
||||
logger.error("Error setting value from L2 cache", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCacheDataValue(EntityBean bean) {
|
||||
try {
|
||||
Object collection = getValue(bean);
|
||||
if (collection == null) {
|
||||
return null;
|
||||
}
|
||||
return jsonWriteCollection(collection);
|
||||
} catch (Exception e) {
|
||||
logger.error("Error building value element collection json for L2 cache", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the collection to JSON.
|
||||
*/
|
||||
public String jsonWriteCollection(Object value) throws IOException {
|
||||
StringWriter writer = new StringWriter(300);
|
||||
SpiJsonWriter ctx = descriptor.createJsonWriter(writer);
|
||||
help.jsonWrite(ctx, null, value, false);
|
||||
ctx.flush();
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the collection as JSON.
|
||||
*/
|
||||
public Object jsonReadCollection(String json) throws IOException {
|
||||
SpiJsonReader ctx = descriptor.createJsonReader(json);
|
||||
JsonParser parser = ctx.getParser();
|
||||
JsonToken event = parser.nextToken();
|
||||
if (JsonToken.VALUE_NULL == event) {
|
||||
return null;
|
||||
}
|
||||
return jsonReadCollection(ctx, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the collection to JSON.
|
||||
*/
|
||||
public void jsonWriteCollection(SpiJsonWriter ctx, String name, Object value, boolean explicitInclude) throws IOException {
|
||||
help.jsonWrite(ctx, name, value, explicitInclude);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the collection (JSON Array) containing entity beans.
|
||||
*/
|
||||
public Object jsonReadCollection(ReadJson readJson, EntityBean parentBean) throws IOException {
|
||||
public Object jsonReadCollection(SpiJsonReader readJson, EntityBean parentBean) throws IOException {
|
||||
|
||||
if (elementDescriptor != null && manyType.isMap()) {
|
||||
return elementDescriptor.jsonReadCollection(readJson, parentBean);
|
||||
|
||||
@@ -4,7 +4,7 @@ import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebeaninternal.server.text.json.ReadJson;
|
||||
import io.ebeaninternal.api.json.SpiJsonReader;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -35,7 +35,7 @@ class BeanPropertyAssocManyJsonHelp {
|
||||
/**
|
||||
* Read the JSON for this property.
|
||||
*/
|
||||
public void jsonRead(ReadJson readJson, EntityBean parentBean) throws IOException {
|
||||
public void jsonRead(SpiJsonReader readJson, EntityBean parentBean) throws IOException {
|
||||
|
||||
if (!this.many.jsonDeserialize) {
|
||||
return;
|
||||
@@ -61,7 +61,7 @@ class BeanPropertyAssocManyJsonHelp {
|
||||
/**
|
||||
* Read a Transient property using Jackson ObjectMapper.
|
||||
*/
|
||||
private void jsonReadTransientUsingObjectMapper(ReadJson readJson, EntityBean parentBean) throws IOException {
|
||||
private void jsonReadTransientUsingObjectMapper(SpiJsonReader readJson, EntityBean parentBean) throws IOException {
|
||||
|
||||
if (jsonTransient == null) {
|
||||
throw new IllegalStateException("Jackson ObjectMapper is required to read this Transient property " + many.getFullBeanName());
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@ import com.fasterxml.jackson.databind.type.CollectionType;
|
||||
import com.fasterxml.jackson.databind.type.MapType;
|
||||
import com.fasterxml.jackson.databind.type.TypeFactory;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebeaninternal.server.text.json.ReadJson;
|
||||
import io.ebeaninternal.api.json.SpiJsonReader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -19,7 +19,7 @@ class BeanPropertyAssocManyJsonTransient {
|
||||
/**
|
||||
* Use Jackson ObjectMapper to read the transient 'many' property.
|
||||
*/
|
||||
void jsonReadUsingObjectMapper(BeanPropertyAssocMany<?> many, ReadJson readJson, EntityBean parentBean) throws IOException {
|
||||
void jsonReadUsingObjectMapper(BeanPropertyAssocMany<?> many, SpiJsonReader readJson, EntityBean parentBean) throws IOException {
|
||||
|
||||
ObjectMapper mapper = readJson.getObjectMapper();
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ import io.ebean.bean.EntityBean;
|
||||
import io.ebean.bean.PersistenceContext;
|
||||
import io.ebean.util.SplitName;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.api.json.SpiJsonReader;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.server.cache.CacheChangeSet;
|
||||
import io.ebeaninternal.server.cache.CachedBeanData;
|
||||
import io.ebeaninternal.server.core.DefaultSqlUpdate;
|
||||
@@ -19,8 +21,6 @@ import io.ebeaninternal.server.el.ElPropertyValue;
|
||||
import io.ebeaninternal.server.query.STreePropertyAssocOne;
|
||||
import io.ebeaninternal.server.query.SqlBeanLoad;
|
||||
import io.ebeaninternal.server.query.SqlJoinType;
|
||||
import io.ebeaninternal.server.text.json.ReadJson;
|
||||
import io.ebeaninternal.server.text.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.server.type.ScalarType;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
@@ -740,7 +740,7 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> implements STr
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonRead(ReadJson readJson, EntityBean bean) throws IOException {
|
||||
public void jsonRead(SpiJsonReader readJson, EntityBean bean) throws IOException {
|
||||
if (jsonDeserialize && targetDescriptor != null) {
|
||||
T assocBean = targetDescriptor.jsonRead(readJson, name);
|
||||
setValue(bean, assocBean);
|
||||
|
||||
@@ -2,8 +2,8 @@ package io.ebeaninternal.server.deploy;
|
||||
|
||||
import io.ebean.SqlUpdate;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebeaninternal.api.json.SpiJsonReader;
|
||||
import io.ebeaninternal.server.deploy.meta.DeployBeanPropertySimpleCollection;
|
||||
import io.ebeaninternal.server.text.json.ReadJson;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -19,7 +19,7 @@ public class BeanPropertySimpleCollection<T> extends BeanPropertyAssocMany<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonReadCollection(ReadJson readJson, EntityBean parentBean) throws IOException {
|
||||
public Object jsonReadCollection(SpiJsonReader readJson, EntityBean parentBean) throws IOException {
|
||||
return elementDescriptor.jsonReadCollection(readJson, parentBean);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import io.ebean.bean.BeanCollection;
|
||||
import io.ebean.bean.BeanCollectionAdd;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.common.BeanSet;
|
||||
import io.ebeaninternal.server.text.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashSet;
|
||||
|
||||
@@ -2,7 +2,7 @@ package io.ebeaninternal.server.deploy;
|
||||
|
||||
import io.ebean.bean.BeanCollection;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebeaninternal.server.text.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
|
||||
/**
|
||||
* Helper for element collection List.
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package io.ebeaninternal.server.deploy;
|
||||
|
||||
import io.ebean.bean.BeanCollection;
|
||||
import io.ebean.common.BeanList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -26,7 +29,9 @@ class ElementHelpList implements ElementHelp {
|
||||
|
||||
@Override
|
||||
public Object collection() {
|
||||
return list;
|
||||
BeanList<Object> beanList = new BeanList<>(list);
|
||||
beanList.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
return beanList;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package io.ebeaninternal.server.deploy;
|
||||
|
||||
import io.ebean.bean.BeanCollection;
|
||||
import io.ebean.common.BeanMap;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -26,7 +29,9 @@ class ElementHelpMap implements ElementHelp {
|
||||
|
||||
@Override
|
||||
public Object collection() {
|
||||
return map;
|
||||
BeanMap<Object, Object> beanMap = new BeanMap<>(map);
|
||||
beanMap.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
return beanMap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package io.ebeaninternal.server.deploy;
|
||||
|
||||
import io.ebean.bean.BeanCollection;
|
||||
import io.ebean.common.BeanSet;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -26,7 +29,9 @@ class ElementHelpSet implements ElementHelp {
|
||||
|
||||
@Override
|
||||
public Object collection() {
|
||||
return set;
|
||||
BeanSet<Object> beanSet = new BeanSet<>(set);
|
||||
beanSet.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
return beanSet;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ class AnnotationAssocManys extends AnnotationParser {
|
||||
elementDescriptor.setProperties(new String[]{"value"});
|
||||
} else {
|
||||
elementDescriptor.setProperties(new String[]{"key", "value"});
|
||||
String dbKeyColumn = "key";
|
||||
String dbKeyColumn = "mkey";
|
||||
MapKeyColumn mapKeyColumn = get(prop, MapKeyColumn.class);
|
||||
if (mapKeyColumn != null) {
|
||||
dbKeyColumn = mapKeyColumn.name();
|
||||
|
||||
@@ -6,12 +6,18 @@ import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.SpiTransaction;
|
||||
import io.ebeaninternal.server.core.PersistRequestBean;
|
||||
import io.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Base for saving entity bean collections and element collections.
|
||||
*/
|
||||
abstract class SaveManyBase {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(SaveManyBase.class);
|
||||
|
||||
final PersistRequestBean<?> request;
|
||||
final SpiEbeanServer server;
|
||||
final boolean insertedParent;
|
||||
@@ -48,4 +54,17 @@ abstract class SaveManyBase {
|
||||
}
|
||||
c.modifyReset();
|
||||
}
|
||||
|
||||
void postElementCollectionUpdate() {
|
||||
if (!insertedParent) {
|
||||
if (request.postElementCollectionUpdate()) {
|
||||
try {
|
||||
String asJson = many.jsonWriteCollection(value);
|
||||
request.addCollectionChange(many.getName(), asJson);
|
||||
} catch (IOException e) {
|
||||
log.error("Error build element collection entry for L2 cache", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,8 +49,6 @@ class SaveManyElementCollection extends SaveManyBase {
|
||||
|
||||
transaction.depth(-1);
|
||||
resetModifyState();
|
||||
if (!insertedParent) {
|
||||
request.postElementCollectionUpdate();
|
||||
}
|
||||
postElementCollectionUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,8 +50,6 @@ class SaveManyElementCollectionMap extends SaveManyBase {
|
||||
|
||||
transaction.depth(-1);
|
||||
resetModifyState();
|
||||
if (!insertedParent) {
|
||||
request.postElementCollectionUpdate();
|
||||
}
|
||||
postElementCollectionUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package io.ebeaninternal.server.text.json;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import io.ebean.PersistenceIOException;
|
||||
import io.ebean.bean.PersistenceContext;
|
||||
import io.ebean.text.json.JsonBeanReader;
|
||||
import io.ebeaninternal.api.json.SpiJsonReader;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -18,9 +19,9 @@ public class DJsonBeanReader<T> implements JsonBeanReader<T> {
|
||||
|
||||
private final BeanDescriptor<T> desc;
|
||||
|
||||
private final ReadJson readJson;
|
||||
private final SpiJsonReader readJson;
|
||||
|
||||
public DJsonBeanReader(BeanDescriptor<T> desc, ReadJson readJson) {
|
||||
public DJsonBeanReader(BeanDescriptor<T> desc, SpiJsonReader readJson) {
|
||||
this.desc = desc;
|
||||
this.readJson = readJson;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ import io.ebean.text.json.JsonWriteBeanVisitor;
|
||||
import io.ebean.text.json.JsonWriteOptions;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.SpiJsonContext;
|
||||
import io.ebeaninternal.api.json.SpiJsonReader;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.type.TypeManager;
|
||||
import io.ebeaninternal.util.ParamTypeHelper;
|
||||
@@ -119,7 +121,7 @@ public class DJsonContext implements SpiJsonContext {
|
||||
public <T> T toBean(Class<T> cls, JsonParser parser, JsonReadOptions options) throws JsonIOException {
|
||||
|
||||
BeanDescriptor<T> desc = getDescriptor(cls);
|
||||
ReadJson readJson = new ReadJson(desc, parser, options, determineObjectMapper(options));
|
||||
SpiJsonReader readJson = new ReadJson(desc, parser, options, determineObjectMapper(options));
|
||||
try {
|
||||
return desc.jsonRead(readJson, null);
|
||||
} catch (IOException e) {
|
||||
@@ -131,7 +133,7 @@ public class DJsonContext implements SpiJsonContext {
|
||||
public <T> DJsonBeanReader<T> createBeanReader(Class<T> cls, JsonParser parser, JsonReadOptions options) throws JsonIOException {
|
||||
|
||||
BeanDescriptor<T> desc = getDescriptor(cls);
|
||||
ReadJson readJson = new ReadJson(desc, parser, options, determineObjectMapper(options));
|
||||
SpiJsonReader readJson = new ReadJson(desc, parser, options, determineObjectMapper(options));
|
||||
return new DJsonBeanReader<>(desc, readJson);
|
||||
}
|
||||
|
||||
@@ -139,7 +141,7 @@ public class DJsonContext implements SpiJsonContext {
|
||||
public <T> DJsonBeanReader<T> createBeanReader(BeanType<T> beanType, JsonParser parser, JsonReadOptions options) throws JsonIOException {
|
||||
|
||||
BeanDescriptor<T> desc = (BeanDescriptor<T>) beanType;
|
||||
ReadJson readJson = new ReadJson(desc, parser, options, determineObjectMapper(options));
|
||||
SpiJsonReader readJson = new ReadJson(desc, parser, options, determineObjectMapper(options));
|
||||
return new DJsonBeanReader<>(desc, readJson);
|
||||
}
|
||||
|
||||
@@ -172,7 +174,7 @@ public class DJsonContext implements SpiJsonContext {
|
||||
public <T> List<T> toList(Class<T> cls, JsonParser src, JsonReadOptions options) throws JsonIOException {
|
||||
|
||||
BeanDescriptor<T> desc = getDescriptor(cls);
|
||||
ReadJson readJson = new ReadJson(desc, src, options, determineObjectMapper(options));
|
||||
SpiJsonReader readJson = new ReadJson(desc, src, options, determineObjectMapper(options));
|
||||
try {
|
||||
|
||||
JsonToken currentToken = src.getCurrentToken();
|
||||
@@ -304,7 +306,7 @@ public class DJsonContext implements SpiJsonContext {
|
||||
|
||||
private String toJsonString(Object value, JsonWriteOptions options) throws JsonIOException {
|
||||
StringWriter writer = new StringWriter(500);
|
||||
try (JsonGenerator gen = createGenerator(writer)){
|
||||
try (JsonGenerator gen = createGenerator(writer)) {
|
||||
toJsonInternal(value, gen, options);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
@@ -342,6 +344,14 @@ public class DJsonContext implements SpiJsonContext {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpiJsonReader createJsonRead(BeanType<?> beanType, String json) {
|
||||
|
||||
BeanDescriptor<?> desc = (BeanDescriptor<?>) beanType;
|
||||
JsonParser parser = createParser(new StringReader(json));
|
||||
return new ReadJson(desc, parser, null, defaultObjectMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpiJsonWriter createJsonWriter(Writer writer) {
|
||||
JsonGenerator generator = createGenerator(writer);
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
package io.ebeaninternal.server.text.json;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.bean.EntityBeanIntercept;
|
||||
import io.ebean.bean.PersistenceContext;
|
||||
import io.ebean.text.json.JsonReadBeanVisitor;
|
||||
import io.ebean.text.json.JsonReadOptions;
|
||||
import io.ebeaninternal.api.LoadContext;
|
||||
import io.ebeaninternal.api.json.SpiJsonReader;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.loadcontext.DLoadContext;
|
||||
import io.ebeaninternal.server.transaction.DefaultPersistenceContext;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
@@ -19,7 +20,7 @@ import java.util.Map;
|
||||
/**
|
||||
* Context for JSON read processing.
|
||||
*/
|
||||
public class ReadJson {
|
||||
public class ReadJson implements SpiJsonReader {
|
||||
|
||||
private final BeanDescriptor<?> rootDesc;
|
||||
|
||||
@@ -100,6 +101,7 @@ public class ReadJson {
|
||||
/**
|
||||
* Return the persistence context being used if any.
|
||||
*/
|
||||
@Override
|
||||
public PersistenceContext getPersistenceContext() {
|
||||
return persistenceContext;
|
||||
}
|
||||
@@ -107,13 +109,15 @@ public class ReadJson {
|
||||
/**
|
||||
* Return a new instance of ReadJson using the existing context but with a new JsonParser.
|
||||
*/
|
||||
public ReadJson forJson(JsonParser moreJson, boolean resetContext) {
|
||||
@Override
|
||||
public SpiJsonReader forJson(JsonParser moreJson, boolean resetContext) {
|
||||
return new ReadJson(moreJson, this, resetContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the bean to the persistence context.
|
||||
*/
|
||||
@Override
|
||||
public <T> void persistenceContextPut(Object beanId, T currentBean) {
|
||||
|
||||
persistenceContextPutIfAbsent(beanId, (EntityBean) currentBean, rootDesc);
|
||||
@@ -123,6 +127,7 @@ public class ReadJson {
|
||||
* Put the bean into the persistence context. If there is already a matching bean in the
|
||||
* persistence context then return that instance else return null.
|
||||
*/
|
||||
@Override
|
||||
public Object persistenceContextPutIfAbsent(Object id, EntityBean bean, BeanDescriptor<?> beanDesc) {
|
||||
|
||||
if (persistenceContext == null) {
|
||||
@@ -153,6 +158,7 @@ public class ReadJson {
|
||||
/**
|
||||
* Return the objectMapper used for this request.
|
||||
*/
|
||||
@Override
|
||||
public ObjectMapper getObjectMapper() {
|
||||
if (objectMapper == null) {
|
||||
throw new IllegalStateException(
|
||||
@@ -165,6 +171,7 @@ public class ReadJson {
|
||||
/**
|
||||
* Return the JsonParser.
|
||||
*/
|
||||
@Override
|
||||
public JsonParser getParser() {
|
||||
return parser;
|
||||
}
|
||||
@@ -172,6 +179,7 @@ public class ReadJson {
|
||||
/**
|
||||
* Return the next JsonToken from the underlying parser.
|
||||
*/
|
||||
@Override
|
||||
public JsonToken nextToken() throws IOException {
|
||||
return parser.nextToken();
|
||||
}
|
||||
@@ -179,6 +187,7 @@ public class ReadJson {
|
||||
/**
|
||||
* Push the path onto the stack (traversing a 1-M or M-1 etc)
|
||||
*/
|
||||
@Override
|
||||
public void pushPath(String path) {
|
||||
if (pathStack != null) {
|
||||
pathStack.pushPathKey(path);
|
||||
@@ -188,6 +197,7 @@ public class ReadJson {
|
||||
/**
|
||||
* Pop the path stack.
|
||||
*/
|
||||
@Override
|
||||
public void popPath() {
|
||||
if (pathStack != null) {
|
||||
pathStack.pop();
|
||||
@@ -198,6 +208,7 @@ public class ReadJson {
|
||||
* If there is a JsonReadBeanVisitor registered to the current path then
|
||||
* call it's visit method with the bean and unmappedProperties.
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public void beanVisitor(Object bean, Map<String, Object> unmappedProperties) {
|
||||
if (visitorMap != null) {
|
||||
@@ -213,6 +224,7 @@ public class ReadJson {
|
||||
* <p/>
|
||||
* Typically this is used to read Transient properties where the type is unknown to Ebean.
|
||||
*/
|
||||
@Override
|
||||
public Object readValueUsingObjectMapper(Class<?> propertyType) throws IOException {
|
||||
return getObjectMapper().readValue(parser, propertyType);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import io.ebean.text.json.EJson;
|
||||
import io.ebean.text.json.JsonIOException;
|
||||
import io.ebean.text.json.JsonWriteBeanVisitor;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.deploy.BeanProperty;
|
||||
import io.ebeaninternal.server.util.ArrayStack;
|
||||
@@ -89,6 +90,11 @@ public class WriteJson implements SpiJsonWriter {
|
||||
return generator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
generator.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeStartObject(String key) {
|
||||
try {
|
||||
@@ -373,7 +379,9 @@ public class WriteJson implements SpiJsonWriter {
|
||||
public void beginAssocMany(String key) {
|
||||
try {
|
||||
pathStack.pushPathKey(key);
|
||||
generator.writeFieldName(key);
|
||||
if (key != null) {
|
||||
generator.writeFieldName(key);
|
||||
}
|
||||
generator.writeStartArray();
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
|
||||
Reference in New Issue
Block a user