是否将null存储为实体属性的值?

时间:2018-08-20 16:04:11

标签: java xodus

由于实体存储在存储空值时已被淘汰,因此我设法获得一个“ 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;
    }
}

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;
    }

}

恐怕我的方法对于保存空值的简单工作可能有点过大了?

1 个答案:

答案 0 :(得分:1)

多次registerCustomPropertyType是安全的,尽管它通常在初始化阶段被调用一次。

如果我真的需要区分缺少属性值和具有空值的属性,那么我将尝试定义非空值来替换空值。对于String,它可以是UUID的十六进制表示。对于IntegerInteger.MIN_VALUEInteger.MAX_VALUE等,请勿对单个属性使用混合类型的值,否则按属性值搜索或范围搜索将不起作用。