java - 将 null 存储为实体属性的值?
问题描述
由于实体存储在存储空值时会被丢弃,因此我设法获得了一个“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 请求时都会调用此方法。
接下来是UndefinedIterable
这里需要的偶数吗?
这是完整的代码
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;
}
}
未定义绑定.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 的十六进制表示。For Integer
, Integer.MIN_VALUE
orInteger.MAX_VALUE
等。不要对单个属性使用混合类型的值,否则按属性值搜索或范围搜索将不起作用。
推荐阅读
- android - 当应用程序处于背景中时,我的 Android 应用程序没有发出通知
- python - Python 没有检测到我的一个对象的碰撞
- hadoop - 为初始化指定的未知版本:3.1.0 schemaTool 失败
- javascript - 当我尝试从 Google 表格中获取数据时,如果此数据包含日期或时间,则不会将其提取到 Google 应用脚本中
- c++ - 如何在 Windows 应用程序中捕获 ossPrint?
- python - FloatingPointError:在日志 TransformedTargetRegressor 中遇到除以零
- python - 带有预定义映射然后索引文档的 Elasticsearch 问题
- bash - 用户切换命令后未执行 Bash 脚本命令
- java - 从接口和方法创建一个类以将对象用作字符串
- c# - 创建进程时隐藏所有子进程