Since Entity store is throwing out when storing null value, I managed to get a "hack" to save a null value into it. However I am not sure if my approach is futile.
Here's a snippet:
entityStore.executeInTransaction(new StoreTransactionalExecutable() {
@Override
public void execute(@NotNull final StoreTransaction txn) {
try {
entityStore.registerCustomPropertyType(txn, UndefinedIterable.class, UndefinedBinding.BINDING);
} catch (Exception e) {
}
final Entity entity = txn.newEntity(storeName);
Iterator<String> it = comparableMap.keySet().iterator();
while (it.hasNext()) {
String key = it.next();
Comparable value = comparableMap.get(key);
if(value == null) {
entity.setProperty(key, new UndefinedIterable());
} else {
entity.setProperty(key, value);
}
}
First question here is, is it safe to registerCustomPropertyType
over and over again, since this method will be called each time the server gets a POST request.
Next is the UndefinedIterable
even needed here?
Here's the complete code
UndefinedIterable.java
public class UndefinedIterable implements Serializable, ByteIterable {
private byte[] bytes;
public UndefinedIterable() {
bytes = "null".getBytes();
}
@Override
public ByteIterator iterator() {
return new ArrayByteIterable(bytes).iterator();
}
@Override
public byte[] getBytesUnsafe() {
return bytes;
}
@Override
public int getLength() {
return bytes.length;
}
@NotNull
@Override
public ByteIterable subIterable(int offset, int length) {
return null;
}
@Override
public int compareTo(@NotNull ByteIterable o) {
return 0;
}
}
UndefinedBinding.java
public class UndefinedBinding extends ComparableBinding {
public static final UndefinedBinding BINDING = new UndefinedBinding();
@Override
public Comparable readObject(@NotNull ByteArrayInputStream stream) {
try {
byte[] serialized = ByteStreams.toByteArray(stream);
Comparable deserialized = deserialize(serialized, Comparable.class);
return deserialized;
} catch (Exception e) {
}
return null;
}
@Override
public void writeObject(@NotNull LightOutputStream output, @NotNull Comparable object) {
byte[] serialized = serialize(object);
output.write(serialized);
}
public static byte[] serialize(Object obj) {
try {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutput out = new ObjectOutputStream(bos)) {
out.writeObject(obj);
return bos.toByteArray();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static <T> T deserialize(byte[] data, Class<T> clazz) {
try {
ByteArrayInputStream in = new ByteArrayInputStream(data);
ObjectInputStream is = new ObjectInputStream(in);
return (T) is.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
I am afraid that my approach might be a bit overkill for the simple job of saving a null value?