diff --git a/ebean-api/pom.xml b/ebean-api/pom.xml
index d3868ff91..649f85822 100644
--- a/ebean-api/pom.xml
+++ b/ebean-api/pom.xml
@@ -50,7 +50,7 @@
io.ebean
ebean-annotation
- 7.0
+ 7.1
diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java
index 40c90d853..c7fba7b8b 100644
--- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java
+++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java
@@ -15,16 +15,24 @@ import java.util.Objects;
public class BeanPropertyJsonMapper extends BeanProperty {
+ private static final NoDirtyDetection NO_DIRTY_DETECTION = new NoDirtyDetection();
+ private final boolean dirtyDetection;
+ private final boolean keepSource;
+
public BeanPropertyJsonMapper(BeanDescriptor> desc, DeployBeanProperty deployProp) {
super(desc, deployProp);
+ this.dirtyDetection = deployProp.isDirtyDetection();
+ this.keepSource = deployProp.isKeepSource();
}
@Override
public MutableHash createMutableHash(String json) {
- if (false) { // TODO should we make that configurable?
- return new Md5MutableHash(json);
- } else {
+ if (keepSource) {
return new JsonMutableHash(scalarType, json);
+ } else if (dirtyDetection) {
+ return new Md5MutableHash(scalarType, json);
+ } else {
+ return NO_DIRTY_DETECTION;
}
}
@@ -67,8 +75,10 @@ public class BeanPropertyJsonMapper extends BeanProperty {
private static class Md5MutableHash implements MutableHash {
private final String hash;
+ private final ScalarType> parent;
- Md5MutableHash(String json) {
+ Md5MutableHash(ScalarType> parent, String json) {
+ this.parent = parent;
this.hash = hash(json);
}
@@ -78,7 +88,7 @@ public class BeanPropertyJsonMapper extends BeanProperty {
@Override
public boolean isEqualToObject(Object obj) {
- return true; // we cannot determine differences...
+ return isEqualToJson(parent.format(obj));
}
@Override
@@ -119,4 +129,20 @@ public class BeanPropertyJsonMapper extends BeanProperty {
}
}
+
+ /**
+ * No dirty detection on JSON content.
+ */
+ private static class NoDirtyDetection implements MutableHash {
+
+ @Override
+ public boolean isEqualToJson(String json) {
+ return true;
+ }
+
+ @Override
+ public boolean isEqualToObject(Object obj) {
+ return true;
+ }
+ }
}
diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanProperty.java
index 92ad7f1e9..060ce802f 100644
--- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanProperty.java
+++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanProperty.java
@@ -109,6 +109,8 @@ public class DeployBeanProperty {
private boolean jsonSerialize = true;
private boolean jsonDeserialize = true;
+ private boolean dirtyDetection;
+ private boolean keepSource;
private boolean dbEncrypted;
private DbEncryptFunction dbEncryptFunction;
@@ -327,6 +329,20 @@ public class DeployBeanProperty {
this.jsonDeserialize = jsonDeserialize;
}
+ /**
+ * Return true if we should have JSON dirty detection on this property.
+ */
+ public boolean isDirtyDetection() {
+ return dirtyDetection;
+ }
+
+ /**
+ * Return true if we should store source JSON content on this property.
+ */
+ public boolean isKeepSource() {
+ return keepSource;
+ }
+
/**
* Return the sortOrder for the properties.
*/
@@ -1204,4 +1220,9 @@ public class DeployBeanProperty {
boolean isJsonMapper() {
return scalarType != null && scalarType.isJsonMapper();
}
+
+ public void setJsonOptions(boolean dirtyDetection, boolean keepSource) {
+ this.dirtyDetection = dirtyDetection;
+ this.keepSource = keepSource;
+ }
}
diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployUtil.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployUtil.java
index 65c7cf45e..2245b0c4c 100644
--- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployUtil.java
+++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployUtil.java
@@ -213,23 +213,22 @@ public class DeployUtil {
* This property is marked as a Lob object.
*/
void setDbJsonType(DeployBeanProperty prop, DbJson dbJsonType) {
-
int dbType = getDbJsonStorage(dbJsonType.storage());
- setDbJsonType(prop, dbType, dbJsonType.length());
+ setDbJsonType(prop, dbType, dbJsonType.length(), dbJsonType.dirtyDetection(), dbJsonType.keepSource());
}
void setDbJsonBType(DeployBeanProperty prop, DbJsonB dbJsonB) {
- setDbJsonType(prop, DbPlatformType.JSONB, dbJsonB.length());
+ setDbJsonType(prop, DbPlatformType.JSONB, dbJsonB.length(), dbJsonB.dirtyDetection(), dbJsonB.keepSource());
}
- private void setDbJsonType(DeployBeanProperty prop, int dbType, int dbLength) {
-
+ private void setDbJsonType(DeployBeanProperty prop, int dbType, int dbLength, boolean dirtyDetection, boolean keepSource) {
ScalarType> scalarType = typeManager.getJsonScalarType(prop, dbType, dbLength);
if (scalarType == null) {
throw new RuntimeException("No ScalarType for JSON property [" + prop + "] [" + dbType + "]");
}
prop.setDbType(dbType);
prop.setScalarType(scalarType);
+ prop.setJsonOptions(dirtyDetection, keepSource);
if (dbType == Types.VARCHAR || dbLength > 0) {
// determine the db column size
int columnLength = (dbLength > 0) ? dbLength : DEFAULT_JSON_VARCHAR_LENGTH;
diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonObjectMapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonObjectMapper.java
index 2c3be2fa3..14425c6c9 100644
--- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonObjectMapper.java
+++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonObjectMapper.java
@@ -7,8 +7,6 @@ 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.MutableHash;
import io.ebean.core.type.DataBinder;
import io.ebean.core.type.DataReader;
import io.ebean.core.type.DocPropertyType;
@@ -17,7 +15,6 @@ 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;
@@ -27,7 +24,6 @@ import java.sql.SQLException;
import java.sql.Types;
import java.util.List;
import java.util.Map;
-import java.util.Objects;
import java.util.Set;
/**
diff --git a/ebean-core/src/test/java/org/tests/model/json/EBasicJsonList.java b/ebean-core/src/test/java/org/tests/model/json/EBasicJsonList.java
index 22b32e3e1..05d9807b5 100644
--- a/ebean-core/src/test/java/org/tests/model/json/EBasicJsonList.java
+++ b/ebean-core/src/test/java/org/tests/model/json/EBasicJsonList.java
@@ -31,7 +31,7 @@ public class EBasicJsonList {
@DbJson(length = 700)
Map beanMap = new LinkedHashMap<>();
- @DbJson(length = 500)
+ @DbJson(length = 500, keepSource = true) // such that we can rebuild old values
PlainBean plainBean;
@DbJson(length = 50)