Merge branch 'master' of github.com:ebean-orm/ebean

This commit is contained in:
rob bygrave
2018-10-26 01:34:36 +13:00
15 changed files with 556 additions and 42 deletions
@@ -223,6 +223,8 @@ public class DeployBeanDescriptor<T> {
private short profileId;
private Object jacksonAnnotatedClass;
/**
* Construct the BeanDescriptor.
*/
@@ -1238,6 +1240,7 @@ public class DeployBeanDescriptor<T> {
this.descriptor = descriptor;
}
@Override
public String getDeployWord(String expression) {
return descriptor.getDeployWord(expression);
}
@@ -1252,4 +1255,16 @@ public class DeployBeanDescriptor<T> {
return (property == null) ? null : "${ta}." + property.getDbColumn();
}
/**
* Returns the jackson annotated class, if jackson is present.
*/
public Object /*AnnotatedClass*/ getJacksonAnnotatedClass() {
if (jacksonAnnotatedClass == null) {
com.fasterxml.jackson.databind.ObjectMapper objectMapper = (com.fasterxml.jackson.databind.ObjectMapper) serverConfig.getObjectMapper();
com.fasterxml.jackson.databind.JavaType javaType = objectMapper.getTypeFactory().constructType(beanType);
jacksonAnnotatedClass = com.fasterxml.jackson.databind.introspect.AnnotatedClassResolver
.resolve(objectMapper.getDeserializationConfig(), javaType, objectMapper.getDeserializationConfig());
}
return jacksonAnnotatedClass;
}
}
@@ -1124,4 +1124,18 @@ public class DeployBeanProperty {
public void setElementProperty() {
this.elementProperty = true;
}
/**
* Returns the jackson annotated field, if jackson is present.
*/
public Object /*AnnotatedField*/ getJacksonField() {
com.fasterxml.jackson.databind.introspect.AnnotatedClass jac =
(com.fasterxml.jackson.databind.introspect.AnnotatedClass) getDesc().getJacksonAnnotatedClass();
for (com.fasterxml.jackson.databind.introspect.AnnotatedField candidate : jac.fields()) {
if (candidate.getName().equals(getName())) {
return candidate;
}
}
return null;
}
}
@@ -239,10 +239,9 @@ public class DeployUtil {
private void setDbJsonType(DeployBeanProperty prop, int dbType, int dbLength) {
Class<?> type = prop.getPropertyType();
ScalarType<?> scalarType = typeManager.getJsonScalarType(type, dbType, dbLength, prop.getGenericType());
ScalarType<?> scalarType = typeManager.getJsonScalarType(prop, dbType, dbLength);
if (scalarType == null) {
throw new RuntimeException("No ScalarType for JSON type [" + type + "] [" + dbType + "]");
throw new RuntimeException("No ScalarType for JSON property [" + prop + "] [" + dbType + "]");
}
prop.setDbType(dbType);
prop.setScalarType(scalarType);
@@ -2,6 +2,8 @@ package io.ebeaninternal.server.type;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.introspect.AnnotatedField;
import io.ebean.annotation.DbArray;
import io.ebean.annotation.DbEnumType;
import io.ebean.annotation.DbEnumValue;
@@ -17,6 +19,7 @@ import io.ebean.util.AnnotationUtil;
import io.ebeaninternal.api.ExtraTypeFactory;
import io.ebeaninternal.dbmigration.DbOffline;
import io.ebeaninternal.server.core.bootup.BootupClasses;
import io.ebeaninternal.server.deploy.meta.DeployBeanProperty;
import io.ebeanservice.docstore.api.mapping.DocPropertyType;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
@@ -379,31 +382,36 @@ public final class DefaultTypeManager implements TypeManager {
}
@Override
public ScalarType<?> getJsonScalarType(Class<?> type, int dbType, int dbLength, Type genericType) {
public ScalarType<?> getJsonScalarType(DeployBeanProperty prop, int dbType, int dbLength) {
Class<?> type = prop.getPropertyType();
Type genericType = prop.getGenericType();
boolean hasJacksonAnnotations = objectMapperPresent && checkJacksonAnnotations(prop);
if (type.equals(List.class)) {
DocPropertyType docType = getDocType(genericType);
if (isValueTypeSimple(genericType)) {
if (!hasJacksonAnnotations && isValueTypeSimple(genericType)) {
return ScalarTypeJsonList.typeFor(postgres, dbType, docType);
} else {
return createJsonObjectMapperType(type, genericType, dbType, docType);
return createJsonObjectMapperType(prop, dbType, docType);
}
}
if (type.equals(Set.class)) {
DocPropertyType docType = getDocType(genericType);
if (isValueTypeSimple(genericType)) {
if (!hasJacksonAnnotations && isValueTypeSimple(genericType)) {
return ScalarTypeJsonSet.typeFor(postgres, dbType, docType);
} else {
return createJsonObjectMapperType(type, genericType, dbType, docType);
return createJsonObjectMapperType(prop, dbType, docType);
}
}
if (type.equals(Map.class)) {
if (isMapValueTypeObject(genericType)) {
if (!hasJacksonAnnotations && isMapValueTypeObject(genericType)) {
return ScalarTypeJsonMap.typeFor(postgres, dbType);
} else {
return createJsonObjectMapperType(type, genericType, dbType, DocPropertyType.OBJECT);
return createJsonObjectMapperType(prop, dbType, DocPropertyType.OBJECT);
}
}
@@ -426,7 +434,15 @@ public final class DefaultTypeManager implements TypeManager {
}
}
return createJsonObjectMapperType(type, type, dbType, DocPropertyType.OBJECT);
return createJsonObjectMapperType(prop, dbType, DocPropertyType.OBJECT);
}
/**
* Returns TRUE, if there is any jackson annotation on that property. All jackson annotations
* are annotated with the &#64;JacksonAnnotation meta annotation. So detection is easy.
*/
private boolean checkJacksonAnnotations(DeployBeanProperty prop) {
return AnnotationUtil.findAnnotation(prop.getField(), com.fasterxml.jackson.annotation.JacksonAnnotation.class) != null;
}
private DocPropertyType getDocType(Type genericType) {
@@ -459,11 +475,12 @@ public final class DefaultTypeManager implements TypeManager {
return Object.class.equals(typeArgs[1]) || "?".equals(typeArgs[1].toString());
}
private ScalarType<?> createJsonObjectMapperType(Class<?> type, Type genericType, int dbType, DocPropertyType docType) {
private ScalarType<?> createJsonObjectMapperType(DeployBeanProperty prop, int dbType, DocPropertyType docType) {
Class<?> type = prop.getPropertyType();
if (objectMapper == null) {
throw new IllegalArgumentException("Type [" + type + "] unsupported for @DbJson mapping - Jackson ObjectMapper not present");
}
return ScalarTypeJsonObjectMapper.createTypeFor(postgres, type, (ObjectMapper) objectMapper, genericType, dbType, docType);
return ScalarTypeJsonObjectMapper.createTypeFor(postgres, (AnnotatedField) prop.getJacksonField(), (ObjectMapper) objectMapper, dbType, docType);
}
/**
@@ -9,14 +9,19 @@ import io.ebeanservice.docstore.api.mapping.DocPropertyType;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.introspect.AnnotatedField;
import javax.persistence.PersistenceException;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.lang.reflect.Type;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List;
@@ -31,20 +36,21 @@ public class ScalarTypeJsonObjectMapper {
/**
* Create and return the appropriate ScalarType.
*/
public static ScalarType<?> createTypeFor(boolean postgres, Class<?> type, ObjectMapper objectMapper,
Type genericType, int dbType, DocPropertyType docType) {
public static ScalarType<?> createTypeFor(boolean postgres, AnnotatedField field, ObjectMapper objectMapper,
int dbType, DocPropertyType docType) {
Class<?> type = field.getRawType();
String pgType = getPostgresType(postgres, dbType);
if (Set.class.equals(type)) {
return new OmSet(objectMapper, genericType, dbType, pgType, docType);
return new OmSet(objectMapper, field, dbType, pgType, docType);
}
if (List.class.equals(type)) {
return new OmList(objectMapper, genericType, dbType, pgType, docType);
return new OmList(objectMapper, field, dbType, pgType, docType);
}
if (Map.class.equals(type)) {
return new OmMap(objectMapper, genericType, dbType, pgType);
return new OmMap(objectMapper, field, dbType, pgType);
}
return new GenericObject(objectMapper, genericType, dbType, pgType);
return new GenericObject(objectMapper, field, dbType, pgType);
}
private static String getPostgresType(boolean postgres, int dbType) {
@@ -64,8 +70,8 @@ public class ScalarTypeJsonObjectMapper {
*/
private static class GenericObject extends Base<Object> {
public GenericObject(ObjectMapper objectMapper, Type type, int dbType, String pgType) {
super(Object.class, objectMapper, type, dbType, pgType, DocPropertyType.OBJECT);
public GenericObject(ObjectMapper objectMapper, AnnotatedField field, int dbType, String pgType) {
super(Object.class, objectMapper, field, dbType, pgType, DocPropertyType.OBJECT);
}
}
@@ -75,8 +81,8 @@ public class ScalarTypeJsonObjectMapper {
@SuppressWarnings("rawtypes")
private static class OmSet extends Base<Set> {
public OmSet(ObjectMapper objectMapper, Type type, int dbType, String pgType, DocPropertyType docType) {
super(Set.class, objectMapper, type, dbType, pgType, docType);
public OmSet(ObjectMapper objectMapper, AnnotatedField field, int dbType, String pgType, DocPropertyType docType) {
super(Set.class, objectMapper, field, dbType, pgType, docType);
}
@Override
@@ -93,8 +99,8 @@ public class ScalarTypeJsonObjectMapper {
@SuppressWarnings("rawtypes")
private static class OmList extends Base<List> {
public OmList(ObjectMapper objectMapper, Type type, int dbType, String pgType, DocPropertyType docType) {
super(List.class, objectMapper, type, dbType, pgType, docType);
public OmList(ObjectMapper objectMapper, AnnotatedField field, int dbType, String pgType, DocPropertyType docType) {
super(List.class, objectMapper, field, dbType, pgType, docType);
}
@Override
@@ -111,8 +117,8 @@ public class ScalarTypeJsonObjectMapper {
@SuppressWarnings("rawtypes")
private static class OmMap extends Base<Map> {
public OmMap(ObjectMapper objectMapper, Type type, int dbType, String pgType) {
super(Map.class, objectMapper, type, dbType, pgType, DocPropertyType.OBJECT);
public OmMap(ObjectMapper objectMapper, AnnotatedField field, int dbType, String pgType) {
super(Map.class, objectMapper, field, dbType, pgType, DocPropertyType.OBJECT);
}
@Override
@@ -129,9 +135,11 @@ public class ScalarTypeJsonObjectMapper {
*/
private static abstract class Base<T> extends ScalarTypeBase<T> {
private final ObjectMapper objectMapper;
private final ObjectWriter objectWriter;
private final JavaType javaType;
private final ObjectMapper objectReader;
private JavaType deserType;
private final String pgType;
@@ -140,12 +148,39 @@ public class ScalarTypeJsonObjectMapper {
/**
* Construct given the object mapper, property type and DB type for storage.
*/
public Base(Class<T> cls, ObjectMapper objectMapper, Type type, int dbType, String pgType, DocPropertyType docType) {
public Base(Class<T> cls, ObjectMapper objectMapper, AnnotatedField field, int dbType, String pgType, DocPropertyType docType) {
super(cls, false, dbType);
this.pgType = pgType;
this.docType = docType;
this.objectMapper = objectMapper;
this.javaType = objectMapper.getTypeFactory().constructType(type);
this.objectReader = objectMapper;
JavaType javaType = field.getType();
DeserializationConfig deserConfig = objectMapper.getDeserializationConfig();
AnnotationIntrospector ai = deserConfig.getAnnotationIntrospector();
if (ai != null && javaType != null && !javaType.hasRawClass(Object.class)) {
try {
this.deserType = ai.refineDeserializationType(deserConfig, field, javaType);
} catch (JsonMappingException e) {
throw new RuntimeException(e);
}
} else {
this.deserType = javaType;
}
SerializationConfig serConfig = objectMapper.getSerializationConfig();
ai = deserConfig.getAnnotationIntrospector();
if (ai != null && javaType != null && !javaType.hasRawClass(Object.class)) {
try {
JavaType serType = ai.refineSerializationType(serConfig, field, javaType);
this.objectWriter = objectMapper.writerFor(serType);
} catch (JsonMappingException e) {
throw new RuntimeException(e);
}
} else {
this.objectWriter = objectMapper.writerFor(javaType);
}
}
/**
@@ -171,7 +206,7 @@ public class ScalarTypeJsonObjectMapper {
return null;
}
try {
return objectMapper.readValue(json, javaType);
return objectReader.readValue(json, deserType);
} catch (IOException e) {
throw new SQLException("Unable to convert JSON", e);
}
@@ -187,7 +222,7 @@ public class ScalarTypeJsonObjectMapper {
bind.setNull(Types.VARCHAR); // use varchar, otherwise SqlServer/db2 will fail with 'Invalid JDBC data type 5.001.'
} else {
try {
String json = objectMapper.writeValueAsString(value);
String json = objectWriter.writeValueAsString(value);
bind.setString(json);
} catch (JsonProcessingException e) {
throw new SQLException("Unable to create JSON", e);
@@ -212,7 +247,7 @@ public class ScalarTypeJsonObjectMapper {
@Override
public String formatValue(T value) {
try {
return objectMapper.writeValueAsString(value);
return objectWriter.writeValueAsString(value);
} catch (JsonProcessingException e) {
throw new PersistenceException("Unable to create JSON", e);
}
@@ -221,7 +256,7 @@ public class ScalarTypeJsonObjectMapper {
@Override
public T parse(String value) {
try {
return objectMapper.readValue(value, javaType);
return objectReader.readValue(value, deserType);
} catch (IOException e) {
throw new PersistenceException("Unable to convert JSON", e);
}
@@ -244,12 +279,12 @@ public class ScalarTypeJsonObjectMapper {
@Override
public T jsonRead(JsonParser parser) throws IOException {
return objectMapper.readValue(parser, javaType);
return objectReader.readValue(parser, deserType);
}
@Override
public void jsonWrite(JsonGenerator writer, T value) throws IOException {
objectMapper.writeValue(writer, value);
objectWriter.writeValue(writer, value);
}
@Override
@@ -1,6 +1,7 @@
package io.ebeaninternal.server.type;
import io.ebean.annotation.DbArray;
import io.ebeaninternal.server.deploy.meta.DeployBeanProperty;
import javax.persistence.EnumType;
import java.lang.reflect.Type;
@@ -57,7 +58,7 @@ public interface TypeManager {
* Note that type expected to be JsonNode or Map.
* </p>
*/
ScalarType<?> getJsonScalarType(Class<?> type, int dbType, int dbLength, Type genericType);
ScalarType<?> getJsonScalarType(DeployBeanProperty prop, int dbType, int dbLength);
/**
* Return the ScalarType used to handle DB ARRAY.
@@ -54,7 +54,7 @@ public class TestTransient extends BaseTestCase {
selected = c.getSelected();
Assert.assertNotNull(selected);
String updateStmt = "update customer set name = 'Rob' where id = :id";
String updateStmt = "update customer set name = 'testTrans2' where id = :id";
int rows = Ebean.createUpdate(Customer.class, updateStmt).set("id", custId).execute();
Assert.assertTrue("changed name back", 1 == rows);
@@ -0,0 +1,113 @@
package org.tests.json;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.StrictAssertions.assertThat;
import java.io.IOException;
import org.junit.Test;
import org.tests.model.json.EBasicJsonJackson;
import org.tests.model.json.EBasicJsonJackson2;
import org.tests.model.json.LongJacksonType;
import org.tests.model.json.StringJacksonType;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
public class TestDbJson_Jackson extends BaseTestCase {
/**
* This testcase verifies if the &#64;JsonDeserialize Annotation will work properly in ebean.
*/
@Test
public void testJsonDeserializeAnnotation() throws IOException {
EBasicJsonJackson bean = new EBasicJsonJackson();
bean.setName("stuff");
bean.setPlainValue("plain");
bean.getValueSet().add("A");
bean.getValueSet().add("B");
bean.getValueList().add("A");
bean.getValueList().add("B");
bean.getValueMap().put(1, "one");
bean.getValueMap().put(2, "two");
ObjectMapper mapper = (ObjectMapper) Ebean.getDefaultServer().getPluginApi().getServerConfig().getObjectMapper();
String json = mapper.writeValueAsString(bean);
EBasicJsonJackson found = mapper.readValue(json, EBasicJsonJackson.class);
// here we assert, that we can serialize/deserialize that bean with jackson
assertThat(found.getPlainValue()).isEqualTo("plain");
assertThat(found.getValueList()).containsExactly("A", "B");
assertThat(found.getValueSet()).containsExactly("A", "B");
assertThat(found.getValueMap()).containsEntry(1L, "one").containsEntry(2L, "two");
Ebean.save(bean);
// here we do the same and expect, that we can deserialize the bean also
found = Ebean.find(EBasicJsonJackson.class, bean.getId());
assertThat(found.getPlainValue()).isEqualTo("plain");
assertThat(found.getValueList()).containsExactly("A", "B");
assertThat(found.getValueSet()).containsExactly("A", "B");
assertThat(found.getValueMap()).containsEntry(1L, "one").containsEntry(2L, "two");
}
/**
* This testcase verifies if polymorph objects will work in ebean.
*
* for BasicJacksonType there exists two types and has a &#64;JsonTypeInfo
* annotation. It is expected that this information is also honored by ebean.
*/
@Test
public void testPolymorph() throws IOException {
EBasicJsonJackson2 bean = new EBasicJsonJackson2();
bean.setName("stuff");
bean.setPlainValue(new LongJacksonType(42L));
bean.getValueSet().add(new StringJacksonType("A"));
bean.getValueSet().add(new LongJacksonType(7l));
bean.getValueList().add(new StringJacksonType("A"));
bean.getValueList().add(new LongJacksonType(7l));
bean.getValueMap().put(1, new StringJacksonType("A"));
bean.getValueMap().put(2, new LongJacksonType(7l));
ObjectMapper mapper = (ObjectMapper) Ebean.getDefaultServer().getPluginApi().getServerConfig().getObjectMapper();
String json = mapper.writeValueAsString(bean);
assertThat(json)
.contains("\"type\":\"string\"")
.contains("\"type\":\"long\"");
EBasicJsonJackson2 found = mapper.readValue(json, EBasicJsonJackson2.class);
assertThat(found.getPlainValue()).isInstanceOf(LongJacksonType.class);
assertThat(found.getValueList()).hasSize(2);
assertThat(found.getValueSet()).hasSize(2);
assertThat(found.getValueMap()).hasSize(2);;
Ebean.save(bean);
found = Ebean.find(EBasicJsonJackson2.class, bean.getId());
assertThat(found.getPlainValue()).isInstanceOf(LongJacksonType.class);
assertThat(found.getValueList()).hasSize(2);
assertThat(found.getValueSet()).hasSize(2);
assertThat(found.getValueMap()).hasSize(2);;
}
}
@@ -0,0 +1,62 @@
package org.tests.json;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.StrictAssertions.assertThat;
import java.io.IOException;
import org.junit.Test;
import org.tests.model.json.EBasicJsonJackson2;
import org.tests.model.json.LongJacksonType;
import org.tests.model.json.StringJacksonType;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
public class TestDbJson_Jackson2 extends BaseTestCase {
private EBasicJsonJackson2 bean = new EBasicJsonJackson2();
private EBasicJsonJackson2 found;
@Test
public void insert() throws IOException {
bean.setName("stuff");
bean.setPlainValue(new LongJacksonType(42L));
bean.getValueSet().add(new StringJacksonType("A"));
bean.getValueSet().add(new LongJacksonType(7l));
bean.getValueList().add(new StringJacksonType("A"));
bean.getValueList().add(new LongJacksonType(7l));
bean.getValueMap().put(1, new StringJacksonType("A"));
bean.getValueMap().put(2, new LongJacksonType(7l));
ObjectMapper mapper = (ObjectMapper) Ebean.getDefaultServer().getPluginApi().getServerConfig().getObjectMapper();
String json = mapper.writeValueAsString(bean);
found = mapper.readValue(json, EBasicJsonJackson2.class);
assertThat(found.getPlainValue()).isInstanceOf(LongJacksonType.class);
assertThat(found.getValueList()).hasSize(2);
assertThat(found.getValueSet()).hasSize(2);
assertThat(found.getValueMap()).hasSize(2);;
Ebean.save(bean);
found = Ebean.find(EBasicJsonJackson2.class, bean.getId());
assertThat(found.getPlainValue()).isInstanceOf(LongJacksonType.class);
assertThat(found.getValueList()).hasSize(2);
assertThat(found.getValueSet()).hasSize(2);
assertThat(found.getValueMap()).hasSize(2);;
}
}
@@ -0,0 +1,15 @@
package org.tests.model.json;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = As.PROPERTY, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = LongJacksonType.class, name = "long"),
@JsonSubTypes.Type(value = StringJacksonType.class, name = "string")
})
public interface BasicJacksonType<T> {
T getValue();
}
@@ -0,0 +1,101 @@
package org.tests.model.json;
import io.ebean.annotation.DbJson;
import io.ebean.annotation.DbJsonB;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Version;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Entity
public class EBasicJsonJackson {
@Id
Long id;
String name;
@DbJson(length = 700)
@JsonDeserialize(contentAs = String.class)
Set<Object> valueSet = new LinkedHashSet<>();
@DbJsonB
@JsonDeserialize(contentAs = String.class)
List<Object> valueList = new ArrayList<>();
@DbJson(length = 700)
@JsonDeserialize(keyAs = Long.class, contentAs = String.class)
Map<Object, Object> valueMap = new LinkedHashMap<>();
@DbJson(length = 500)
@JsonDeserialize(as = String.class)
Object plainValue;
@Version
Long version;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Object> getValueSet() {
return valueSet;
}
public void setValueSet(Set<Object> valueSet) {
this.valueSet = valueSet;
}
public List<Object> getValueList() {
return valueList;
}
public void setValueList(List<Object> valueList) {
this.valueList = valueList;
}
public Object getPlainValue() {
return plainValue;
}
public void setPlainValue(Object plainValue) {
this.plainValue = plainValue;
}
public Map<Object, Object> getValueMap() {
return valueMap;
}
public void setValueMap(Map<Object, Object> valueMap) {
this.valueMap = valueMap;
}
public Long getVersion() {
return version;
}
public void setVersion(Long version) {
this.version = version;
}
}
@@ -0,0 +1,98 @@
package org.tests.model.json;
import io.ebean.annotation.DbJson;
import io.ebean.annotation.DbJsonB;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Version;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Entity
public class EBasicJsonJackson2 {
@Id
Long id;
String name;
@DbJson(length = 700)
Set<BasicJacksonType<?>> valueSet = new LinkedHashSet<>();
@DbJsonB
List<BasicJacksonType<?>> valueList = new ArrayList<>();
@DbJson(length = 700)
@JsonDeserialize(keyAs = Long.class)
Map<Number, BasicJacksonType<?>> valueMap = new LinkedHashMap<>();
@DbJson(length = 500)
BasicJacksonType<?> plainValue;
@Version
Long version;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<BasicJacksonType<?>> getValueSet() {
return valueSet;
}
public void setValueSet(Set<BasicJacksonType<?>> valueSet) {
this.valueSet = valueSet;
}
public List<BasicJacksonType<?>> getValueList() {
return valueList;
}
public void setValueList(List<BasicJacksonType<?>> valueList) {
this.valueList = valueList;
}
public BasicJacksonType<?> getPlainValue() {
return plainValue;
}
public void setPlainValue(BasicJacksonType<?> plainValue) {
this.plainValue = plainValue;
}
public Map<Number, BasicJacksonType<?>> getValueMap() {
return valueMap;
}
public void setValueMap(Map<Number, BasicJacksonType<?>> valueMap) {
this.valueMap = valueMap;
}
public Long getVersion() {
return version;
}
public void setVersion(Long version) {
this.version = version;
}
}
@@ -0,0 +1,22 @@
package org.tests.model.json;
public class LongJacksonType implements BasicJacksonType<Long> {
private Long value;
public LongJacksonType() {}
public LongJacksonType(Long value) {
this.value = value;
}
@Override
public Long getValue() {
return value;
}
public void setValue(Long value) {
this.value = value;
}
}
@@ -0,0 +1,22 @@
package org.tests.model.json;
public class StringJacksonType implements BasicJacksonType<String> {
private String value;
public StringJacksonType() {}
public StringJacksonType(String value) {
this.value = value;
}
@Override
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
+1 -1
View File
@@ -1,4 +1,4 @@
10000,NEW,"Rob",01-JAN-2009,"12 someplace",Auckland,NZ
10000,NEW,"Roland",01-JAN-2009,"12 someplace",Auckland,NZ
,ACTIVE,"Greg",14-FEB-2009,"13 someplace",Sydney,AU
,INACTIVE,"Dan",29-SEP-2009,"14 someplace",Auckland,NZ
,NEW,"ARob",01-JAN-2009,"12 someplace",Auckland,NZ
1 10000 NEW Rob Roland 01-JAN-2009 12 someplace Auckland NZ
2 ACTIVE Greg 14-FEB-2009 13 someplace Sydney AU
3 INACTIVE Dan 29-SEP-2009 14 someplace Auckland NZ
4 NEW ARob 01-JAN-2009 12 someplace Auckland NZ