由于实体存储在存储空值时会抛出,我设法得到一个“hack”来将空值保存到其中。但我不确定我的方法是否徒劳。
这是一个片段:
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);
}
}
这里的第一个问题是,一遍又一遍registerCustomPropertyType
是否安全,因为每次服务器收到 POST 请求时都会调用此方法。
接下来这里还需要UndefineIterable
吗?
这是完整的代码
UndefineIterable.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;
}
}
我担心我的方法对于保存空值的简单工作来说可能有点矫枉过正?
最佳答案
多次registerCustomPropertyType
是安全的,尽管它通常在初始化阶段调用一次。
如果我确实需要区分缺少属性值和具有空值的属性,那么我会尝试定义非空值来替换空值。对于String
,它可以是 UUID 的十六进制表示形式。对于 Integer
、Integer.MIN_VALUE
或 Integer.MAX_VALUE
等。不要对单个属性使用混合类型的值,否则按属性值或范围搜索将不起作用。
关于java - 将 null 存储为实体属性的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51934571/