Proof of concept to support also bean change detection / changelog on mutable properties

This commit is contained in:
Roland Praml committed 2021-07-28 14:54:56 +02:00
1 parent 49b86d07d3
commit 5e595ec5f8
7 files changed
+180 -16

No files matched your search

@@ -2,6 +2,7 @@ package io.ebeaninternal.server.deploy;
import io.ebean.bean.EntityBean;
import io.ebean.bean.EntityBeanIntercept;
import io.ebean.bean.MutableJson;
import io.ebean.core.type.DataReader;
import io.ebean.text.TextException;
import io.ebeaninternal.server.deploy.meta.DeployBeanProperty;
@@ -25,11 +26,11 @@ public class BeanPropertyJsonMapper extends BeanProperty {
boolean isDirtyValue(Object value, EntityBeanIntercept ebi) {
// dirty detection based on md5 hash of json content
final String json = scalarType.jsonMapper(value);
final String newHash = Md5.hash(json);
final String oldHash = ebi.mutableHash(propertyIndex);
if (!Objects.equals(newHash, oldHash)) {
final MutableJson oldHash = ebi.mutableHash(propertyIndex);
if (oldHash == null || !oldHash.isEqualToJson(json)) {
ebi.mutableContent(propertyIndex, json); // so we only convert to json once
ebi.mutableHash(propertyIndex, newHash); // for dirty detection next time
//ebi.mutableHash(propertyIndex, scalarType.jsonMutable(json)); // for dirty detection next time
//must be done AFTER persistControllers are called.
return true;
}
return false;
@@ -43,8 +44,8 @@ public class BeanPropertyJsonMapper extends BeanProperty {
setValue(bean, value);
String json = reader.popJson();
if (json != null) {
final String hash = Md5.hash(json);
bean._ebean_getIntercept().mutableHash(propertyIndex, hash);
final String hash = scalarType.format(value);
bean._ebean_getIntercept().mutableHash(propertyIndex, scalarType.jsonMutable(hash));
}
}
return value;
@@ -32,8 +32,7 @@ class BindablePropertyJsonInsert extends BindableProperty {
} else {
// on insert store MD5 hash and push json
final String json = prop.format(value);
final String hash = Md5.hash(json);
bean._ebean_getIntercept().mutableHash(propertyIndex, hash);
bean._ebean_getIntercept().mutableHash(propertyIndex, prop.getScalarType().jsonMutable(json));
request.pushJson(json);
request.bind(value, prop);
}
@@ -7,6 +7,8 @@ import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.introspect.AnnotatedField;
import io.ebean.bean.MutableJson;
import io.ebean.core.type.DataBinder;
import io.ebean.core.type.DataReader;
import io.ebean.core.type.DocPropertyType;
@@ -15,6 +17,7 @@ import io.ebean.text.TextException;
import io.ebeaninternal.json.ModifyAwareList;
import io.ebeaninternal.json.ModifyAwareMap;
import io.ebeaninternal.json.ModifyAwareSet;
import io.ebeaninternal.server.util.Md5;
import javax.persistence.PersistenceException;
import java.io.DataInput;
@@ -24,6 +27,7 @@ import java.sql.SQLException;
import java.sql.Types;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
/**
@@ -66,6 +70,66 @@ class ScalarTypeJsonObjectMapper {
public String jsonMapper(Object value) {
return formatValue(value);
}
private class Md5MutableJson implements MutableJson {
private String md5;
Md5MutableJson(String json) {
md5 = Md5.hash(json);
}
@Override
public boolean isEqualToObject(Object obj) {
return true; // we cannot determine differences...
}
@Override
public boolean isEqualToJson(String json) {
return Md5.hash(json).equals(md5);
}
@Override
public Object get() {
return null; // cannot create object from json
}
@Override
public void update(Object obj) {
md5 = Md5.hash(format(obj));
}
}
private class PlainMutableJson implements MutableJson {
private String originalJson;
PlainMutableJson(String json) {
originalJson = json;
}
@Override
public boolean isEqualToObject(Object obj) {
return isEqualToJson(format(obj));
}
@Override
public boolean isEqualToJson(String json) {
return Objects.equals(originalJson, json);
}
@Override
public Object get() {
return parse(originalJson);
}
@Override
public void update(Object obj) {
originalJson = format(obj);
}
}
@Override
public MutableJson jsonMutable(String originalJson) {
if (false) {
return new Md5MutableJson(originalJson);
} else {
return new PlainMutableJson(originalJson);
}
}
@Override
public Object read(DataReader reader) throws SQLException {