On DD4T 2 Java version environment, I created view model class. But, when there is a embedded field in another embedded field, 2nd embedded field values are not mapped to view model instance, and I got following error. (1st embedded field's value is mapped to view model instance normaly.)
How can 2nd embedded field be mapped to view model?
2015-09-15 11:35:53,826 ERROR JsonModelConverter - Error setting field!
com.fasterxml.jackson.databind.JsonMappingException: Unexpected token (END_OBJECT), expected FIELD_NAME: missing property 'FieldType' that is to contain type id (for class org.dd4t.contentmodel.impl.BaseField)
at [Source: N/A; line: -1, column: -1]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148) ~[jackson-databind-2.4.3.jar:2.4.3]
at com.fasterxml.jackson.databind.DeserializationContext.wrongTokenException(DeserializationContext.java:841) ~[jackson-databind-2.4.3.jar:2.4.3]
at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer._deserializeTypedUsingDefaultImpl(AsPropertyTypeDeserializer.java:140) ~[jackson-databind-2.4.3.jar:2.4.3]
at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer.deserializeTypedFromObject(AsPropertyTypeDeserializer.java:92) ~[jackson-databind-2.4.3.jar:2.4.3]
at com.fasterxml.jackson.databind.deser.AbstractDeserializer.deserializeWithType(AbstractDeserializer.java:132) ~[jackson-databind-2.4.3.jar:2.4.3]
at com.fasterxml.jackson.databind.deser.impl.TypeWrappedDeserializer.deserialize(TypeWrappedDeserializer.java:41) ~[jackson-databind-2.4.3.jar:2.4.3]
at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:3023) [jackson-databind-2.4.3.jar:2.4.3]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:1637) [jackson-databind-2.4.3.jar:2.4.3]
at org.dd4t.databind.util.JsonUtils.renderComponentField(JsonUtils.java:46) ~[dd4t-debug.jar:na]
at org.dd4t.databind.builder.json.JsonModelConverter.deserializeGeneric(JsonModelConverter.java:302) [dd4t-debug.jar:na]
at org.dd4t.databind.builder.json.JsonModelConverter.buildField(JsonModelConverter.java:213) [dd4t-debug.jar:na]
at org.dd4t.databind.builder.json.JsonModelConverter.buildModelProperties(JsonModelConverter.java:117) [dd4t-debug.jar:na]
at org.dd4t.databind.builder.json.JsonModelConverter.convertSource(JsonModelConverter.java:94) [dd4t-debug.jar:na]
at org.dd4t.databind.builder.json.JsonDataBinder.buildModel(JsonDataBinder.java:177) [dd4t-debug.jar:na]
at org.dd4t.databind.DataBindFactory.buildModel(DataBindFactory.java:71) [dd4t-debug.jar:na]
at org.dd4t.databind.builder.json.JsonModelConverter.buildModelForField(JsonModelConverter.java:286) [dd4t-debug.jar:na]
at org.dd4t.databind.builder.json.JsonModelConverter.checkTypeAndBuildModel(JsonModelConverter.java:271) [dd4t-debug.jar:na]
at org.dd4t.databind.builder.json.JsonModelConverter.buildField(JsonModelConverter.java:210) [dd4t-debug.jar:na]
at org.dd4t.databind.builder.json.JsonModelConverter.buildModelProperties(JsonModelConverter.java:117) [dd4t-debug.jar:na]
at org.dd4t.databind.builder.json.JsonModelConverter.convertSource(JsonModelConverter.java:94) [dd4t-debug.jar:na]
at org.dd4t.databind.builder.json.JsonDataBinder.buildModel(JsonDataBinder.java:177) [dd4t-debug.jar:na]
at org.dd4t.databind.DataBindFactory.buildModel(DataBindFactory.java:71) [dd4t-debug.jar:na]
at org.dd4t.databind.builder.json.JsonModelConverter.buildModelForField(JsonModelConverter.java:286) [dd4t-debug.jar:na]
at org.dd4t.databind.builder.json.JsonModelConverter.checkTypeAndBuildModel(JsonModelConverter.java:271) [dd4t-debug.jar:na]
at org.dd4t.databind.builder.json.JsonModelConverter.buildField(JsonModelConverter.java:210) [dd4t-debug.jar:na]
at org.dd4t.databind.builder.json.JsonModelConverter.buildModelProperties(JsonModelConverter.java:117) [dd4t-debug.jar:na]
at org.dd4t.databind.builder.json.JsonModelConverter.convertSource(JsonModelConverter.java:94) [dd4t-debug.jar:na]
at org.dd4t.databind.builder.json.JsonDataBinder.buildModel(JsonDataBinder.java:177) [dd4t-debug.jar:na]
at org.dd4t.databind.builder.json.JsonDataBinder.buildModels(JsonDataBinder.java:138) [dd4t-debug.jar:na]
Component XML source code and view model class are following.
Component:
<zzmemorytest xmlns="uuid:5db5a656-6dac-4300-8cc7-ebf76def7dc8">
<text>1 st level text</text>
<emb1>
<text>2nd level text</text>
<emb>
<text>3rd level text</text>
</emb>
</emb1>
</zzmemorytest>
View model class:
@ViewModel(rootElementNames = "TestMemoryTestModel")
public class TestMemoryTestModel extends TridionViewModelBase {
@ViewModelProperty(entityFieldName = "text")
private String text;
@ViewModelProperty(tridionFieldType = FieldType.EMBEDDED, entityFieldName = "emb1")
private TestMemoryTestEmb2Model emb1;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public TestMemoryTestEmb2Model getEmb1() {
return emb1;
}
public void setEmb1(TestMemoryTestEmb2Model emb1) {
this.emb1 = emb1;
}
@ViewModel(rootElementNames = "zzmemorytestemb2")
public static class TestMemoryTestEmb2Model extends TridionViewModelBase {
@ViewModelProperty(entityFieldName = "text")
private String text;
@ViewModelProperty(tridionFieldType = FieldType.EMBEDDED, entityFieldName = "emb")
private TestMemoryTestEmb1Model emb;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public TestMemoryTestEmb1Model getEmb() {
return emb;
}
public void setEmb(TestMemoryTestEmb1Model emb) {
this.emb = emb;
}
}
@ViewModel(rootElementNames = "zzmemorytestemb1")
public static class TestMemoryTestEmb1Model extends TridionViewModelBase {
@ViewModelProperty(entityFieldName = "text")
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
}
UPDATE
After some investigation, it turns out that 2nd embedded field have to be FieldSet class. The embedded field's property looks like following.
@ViewModelProperty(tridionFieldType = FieldType.EMBEDDED, entityFieldName = "emb")
private FieldSet emb;
But, 1st embedded field have to be TridionViewModelBase, not FieldSet.
UPDATE2
I succeeded to map 2nd embedded field value to model class. I added new model class which defines only property for embedded field and, the property's type is second embedded field model class. The new class is "TestMemoryTestEmb1EmbeddedModel" in following new source code. This mode structure is strange, but it works.
Component:
<zzmemorytest xmlns="uuid:5db5a656-6dac-4300-8cc7-ebf76def7dc8">
<textone>textone lv1</textone>
<emb1>
<textembtwo>textembtwo lv2</textembtwo>
<emb>
<textembone>textembone lv3</textembone>
</emb>
</emb1>
</zzmemorytest>
View Model Class:
@ViewModel(rootElementNames = "TestMemoryTestModel")
public class TestMemoryTestModel extends TridionViewModelBase {
@ViewModelProperty(entityFieldName = "textone")
private String text;
@ViewModelProperty(tridionFieldType = FieldType.EMBEDDED, entityFieldName = "emb1")
private TestMemoryTestEmb2Model emb1;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public TestMemoryTestEmb2Model getEmb1() {
return emb1;
}
public void setEmb1(TestMemoryTestEmb2Model emb1) {
this.emb1 = emb1;
}
@ViewModel(rootElementNames = "zzmemorytestemb2")
public static class TestMemoryTestEmb2Model extends TridionViewModelBase {
@ViewModelProperty(entityFieldName = "textembtwo")
private String text;
@ViewModelProperty(tridionFieldType = FieldType.EMBEDDED, entityFieldName = "emb")
private TestMemoryTestEmb1EmbeddedModel emb;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public TestMemoryTestEmb1EmbeddedModel getEmb() {
return emb;
}
public void setEmb(TestMemoryTestEmb1EmbeddedModel emb) {
this.emb = emb;
}
}
/*
* This class is added!
*/
@ViewModel(rootElementNames = "zzmemorytestemb1")
public static class TestMemoryTestEmb1EmbeddedModel extends TridionViewModelBase {
@ViewModelProperty(tridionFieldType = FieldType.EMBEDDED, entityFieldName = "emb")
private TestMemoryTestEmb1Model emb;
public TestMemoryTestEmb1Model getEmb() {
return emb;
}
public void setEmb(TestMemoryTestEmb1Model emb) {
this.emb = emb;
}
}
@ViewModel(rootElementNames = "zzmemorytestemb1")
public static class TestMemoryTestEmb1Model extends TridionViewModelBase {
@ViewModelProperty(entityFieldName = "textembone")
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
}
Regards,