Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIX: mutationDetection = SOURCE works also for special json types #2309

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ public GeoTypeBinder getGeoTypeBinder() {

@Override
public ScalarType<?> getDbMapScalarType() {
return (postgres) ? hstoreType : ScalarTypeJsonMap.typeFor(false, Types.VARCHAR);
return (postgres) ? hstoreType : ScalarTypeJsonMap.typeFor(false, Types.VARCHAR, false);
}

@Override
Expand All @@ -312,7 +312,7 @@ private ScalarType<?> getArrayScalarTypeSet(Type valueType, boolean nullable) {
return arrayTypeSetFactory.typeFor(valueType, nullable);
}
// fallback to JSON storage in VARCHAR column
return new ScalarTypeJsonSet.Varchar(getDocType(valueType), nullable);
return new ScalarTypeJsonSet.Varchar(getDocType(valueType), nullable, false); // TODO: keepSource for @DbArray?
}

private ScalarType<?> getArrayScalarTypeList(Type valueType, boolean nullable) {
Expand All @@ -323,7 +323,7 @@ private ScalarType<?> getArrayScalarTypeList(Type valueType, boolean nullable) {
return arrayTypeListFactory.typeFor(valueType, nullable);
}
// fallback to JSON storage in VARCHAR column
return new ScalarTypeJsonList.Varchar(getDocType(valueType), nullable);
return new ScalarTypeJsonList.Varchar(getDocType(valueType), nullable, false); // TODO: keepSource for @DbArray?
}

private Class<? extends Enum<?>> asEnumClass(Type valueType) {
Expand All @@ -340,30 +340,31 @@ public ScalarType<?> getJsonScalarType(DeployBeanProperty prop, int dbType, int
Type genericType = prop.getGenericType();
boolean hasJacksonAnnotations = objectMapperPresent && checkJacksonAnnotations(prop);

boolean keepSource = prop.getMutationDetection() == MutationDetection.SOURCE;
if (type.equals(List.class)) {
DocPropertyType docType = getDocType(genericType);
if (!hasJacksonAnnotations && isValueTypeSimple(genericType)) {
return ScalarTypeJsonList.typeFor(postgres, dbType, docType, prop.isNullable());
return ScalarTypeJsonList.typeFor(postgres, dbType, docType, prop.isNullable(), keepSource);
} else {
return createJsonObjectMapperType(prop, dbType, docType);
}
}
if (type.equals(Set.class)) {
DocPropertyType docType = getDocType(genericType);
if (!hasJacksonAnnotations && isValueTypeSimple(genericType)) {
return ScalarTypeJsonSet.typeFor(postgres, dbType, docType, prop.isNullable());
return ScalarTypeJsonSet.typeFor(postgres, dbType, docType, prop.isNullable(), keepSource);
} else {
return createJsonObjectMapperType(prop, dbType, docType);
}
}
if (type.equals(Map.class)) {
if (!hasJacksonAnnotations && isMapValueTypeObject(genericType)) {
return ScalarTypeJsonMap.typeFor(postgres, dbType);
return ScalarTypeJsonMap.typeFor(postgres, dbType, keepSource);
} else {
return createJsonObjectMapperType(prop, dbType, DocPropertyType.OBJECT);
}
}
if (objectMapperPresent) {
if (objectMapperPresent && prop.getMutationDetection() == MutationDetection.DEFAULT) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we just remove this altogether ?

if (type.equals(JsonNode.class)) {
switch (dbType) {
case Types.VARCHAR:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,42 +24,42 @@ public class ScalarTypeJsonList {
/**
* Return the appropriate ScalarType based requested dbType and if Postgres.
*/
public static ScalarType<?> typeFor(boolean postgres, int dbType, DocPropertyType docType, boolean nullable) {
public static ScalarType<?> typeFor(boolean postgres, int dbType, DocPropertyType docType, boolean nullable, boolean keepSource) {
if (postgres) {
switch (dbType) {
case DbPlatformType.JSONB:
return new ScalarTypeJsonList.JsonB(docType, nullable);
return new ScalarTypeJsonList.JsonB(docType, nullable, keepSource);
case DbPlatformType.JSON:
return new ScalarTypeJsonList.Json(docType, nullable);
return new ScalarTypeJsonList.Json(docType, nullable, keepSource);
}
}
return new ScalarTypeJsonList.Varchar(docType, nullable);
return new ScalarTypeJsonList.Varchar(docType, nullable, keepSource);
}

/**
* List mapped to DB VARCHAR.
*/
public static class Varchar extends ScalarTypeJsonList.Base {
public Varchar(DocPropertyType docType, boolean nullable) {
super(Types.VARCHAR, docType, nullable);
public Varchar(DocPropertyType docType, boolean nullable, boolean keepSource) {
super(Types.VARCHAR, docType, nullable, keepSource);
}
}

/**
* List mapped to Postgres JSON.
*/
private static class Json extends ScalarTypeJsonList.PgBase {
public Json(DocPropertyType docType, boolean nullable) {
super(DbPlatformType.JSON, PostgresHelper.JSON_TYPE, docType, nullable);
public Json(DocPropertyType docType, boolean nullable, boolean keepSource) {
super(DbPlatformType.JSON, PostgresHelper.JSON_TYPE, docType, nullable, keepSource);
}
}

/**
* List mapped to Postgres JSONB.
*/
private static class JsonB extends ScalarTypeJsonList.PgBase {
public JsonB(DocPropertyType docType, boolean nullable) {
super(DbPlatformType.JSONB, PostgresHelper.JSONB_TYPE, docType, nullable);
public JsonB(DocPropertyType docType, boolean nullable, boolean keepSource) {
super(DbPlatformType.JSONB, PostgresHelper.JSONB_TYPE, docType, nullable, keepSource);
}
}

Expand All @@ -68,14 +68,24 @@ public JsonB(DocPropertyType docType, boolean nullable) {
*/
@SuppressWarnings("rawtypes")
private abstract static class Base extends ScalarTypeJsonCollection<List> {
private final boolean keepSource;

public Base(int dbType, DocPropertyType docType, boolean nullable) {
public Base(int dbType, DocPropertyType docType, boolean nullable, boolean keepSource) {
super(List.class, dbType, docType, nullable);
this.keepSource = keepSource;
}

@Override
public boolean isJsonMapper() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

checkme: Should we refactor that getter to isKeepSource pushSource / popSource

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review this ...

return keepSource;
}

@Override
public List read(DataReader reader) throws SQLException {
String json = reader.getString();
if (isJsonMapper()) {
reader.pushJson(json);
}
try {
// parse JSON into modifyAware list
return EJson.parseList(json, true);
Expand All @@ -85,17 +95,15 @@ public List read(DataReader reader) throws SQLException {
}

@Override
public void bind(DataBinder binder, List value) throws SQLException {
public final void bind(DataBinder binder, List value) throws SQLException {
String rawJson = isJsonMapper() ? binder.popJson() : null;
if (rawJson == null && value != null) {
rawJson = formatValue(value);
}
if (value == null) {
bindNull(binder);
} else if (value.isEmpty()) {
binder.setString("[]");
} else {
try {
binder.setString(EJson.write(value));
} catch (IOException e) {
throw new SQLException("Failed to format List into JSON content", e);
}
bindRawJson(binder, rawJson);
}
}

Expand All @@ -107,9 +115,16 @@ protected void bindNull(DataBinder binder) throws SQLException {
binder.setString("[]");
}
}

protected void bindRawJson(DataBinder binder, String rawJson) throws SQLException {
binder.setString(rawJson);
}

@Override
public String formatValue(List value) {
if (value.isEmpty()) {
return "[]";
}
try {
return EJson.write(value);
} catch (IOException e) {
Expand Down Expand Up @@ -144,19 +159,14 @@ private static class PgBase extends ScalarTypeJsonList.Base {

final String pgType;

PgBase(int jdbcType, String pgType, DocPropertyType docType, boolean nullable) {
super(jdbcType, docType, nullable);
PgBase(int jdbcType, String pgType, DocPropertyType docType, boolean nullable, boolean keepSource) {
super(jdbcType, docType, nullable, keepSource);
this.pgType = pgType;
}

@SuppressWarnings("rawtypes")
@Override
public void bind(DataBinder binder, List value) throws SQLException {
if (value == null) {
bindNull(binder);
} else {
binder.setObject(PostgresHelper.asObject(pgType, formatValue(value)));
}
protected void bindRawJson(DataBinder binder, String rawJson) throws SQLException {
binder.setObject(PostgresHelper.asObject(pgType, rawJson));
}

@Override
Expand Down
Loading