You do not run into this problem if you **just introduce a new attribute for the new type** instead of re-using the existing attribute that already contains other data. Business Data is explicitly designed to allow simple data migration. So it does not throw any errors for unknown fields.
**However, there is a work around**
If you just wrapped the String in a complex object you could work around the problem by influencing the JSON serialization. With Jackson you could for instance store the new complex object also as string and read it back to a complex object. And of course this also allows you to handle legacy serialized objects.
The rough concept is described here: http://developer.axonivy.com/doc/latest/DesignerGuideHtml/ivy.datamodeling.html#ivy.businessdata.serialization.module
A sample implementation could do the following. Here we serialize a complex Person object as a raw String.
FIRST: Write your own serializer module:
package com.axonivy;
import java.io.IOException;
import org.apache.commons.lang3.StringUtils;
import ch.ivyteam.ivy.environment.Ivy;
import com.axonivy.sample.Person;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer;
public class CustomBusinessDataModule extends SimpleModule {
private static final long serialVersionUID = 1L;
private static final String SEPARATOR = "|";
public CustomBusinessDataModule()
{
Ivy.log().info("registered custom module!");
addSerializer(Person.class, new CustomPersonSerializer());
addDeserializer(Person.class, new CustomPersonDeSerializer());
}
@SuppressWarnings("serial")
private static class CustomPersonSerializer extends StdScalarSerializer<Person>
{
public CustomPersonSerializer() {
super(Person.class);
}
@Override
public void serialize(Person value, JsonGenerator gen,
SerializerProvider provider) throws IOException {
gen.writeString(value.getFirstname()+SEPARATOR+value.getLastname());
}
}
@SuppressWarnings("serial")
private static class CustomPersonDeSerializer extends StdScalarDeserializer<Person>
{
public CustomPersonDeSerializer()
{
super(Person.class);
}
@Override
public Person deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
String value = p.readValueAs(String.class);
if (!StringUtils.contains(value, SEPARATOR))
{
// old version.... -> take special care!
return new Person();
}
String[] parts = StringUtils.split(value, SEPARATOR);
Person person = new Person();
person.setFirstname(parts[0]);
person.setLastname(parts[1]);
return person;
}
}
}
SECOND: register it via service SPI:
![alt text][1]
Here you see the custom serializer in action:
[businessDataSerializer_66.iar][2]
![alt text][3]
[1]: http://answers.axonivy.com/upfiles/registerCustomJacksonModule.png
[2]: http://developer.axonivy.com/q-and-a-attachments/businessDataSerializer_66.iar/upfiles/businessDataSerializer_66.iar
[3]: http://answers.axonivy.com/upfiles/customCreatedJson.png