首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java微流列表对象未正确存储

Java微流列表对象未正确存储
EN

Stack Overflow用户
提问于 2020-08-07 21:29:14
回答 1查看 263关注 0票数 1

我有以下对象结构,它扩展了ArrayList。当检索到列表时,列表为null,因此没有一个值存储在微流对象图中。不确定这是否是

bug

  • unsupported特性
  1. a
  2. A CustomHandler必须实现

创建FooTable对象和toString的代码将在

FooTable(super=TableListImpl(super=[a, b, c], tableNo=1, datatableNo=2), baz=baz)

代码语言:javascript
复制
        FooTable foo = new FooTable(1,2);
        foo.setBaz("baz");
        foo.add("a");
        foo.add("b");
        foo.add("c");
        System.out.println(foo1.toString());

将FooTable存储在MicroStream中。停止/启动app/DB并检索FooTable,列表为null。有趣的是,当检查对象变量'size=3‘时。它显示微流无法看到此对象扩展列表的事实,而只保留忽略该列表的其他值。

任何关于如何在不更改对象结构的情况下解决此问题的建议。

注: Lombok在这里是为了简洁而使用。

代码语言:javascript
复制
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString(callSuper = true)
public class FooTable extends TableListImpl<String> {

    public FooTable(int tableNo, int datatableNo) {
        super(tableNo, datatableNo);
    }
    
    private static final long serialVersionUID = 1L;
    private String baz;
    
}
代码语言:javascript
复制
import java.util.ArrayList;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;

@RequiredArgsConstructor
@Getter
@ToString(callSuper = true)
public abstract class TableListImpl<E> extends ArrayList<E> implements TableList<E> {

    private static final long serialVersionUID = 1L;
    private final int tableNo;
    private final int datatableNo;
    
}
代码语言:javascript
复制
import java.util.List;

public interface TableList<E> extends List<E>, Table {

}
代码语言:javascript
复制
public interface Table {

    public int getTableNo();
    public int getDatatableNo();
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-10 14:37:52

这个问题并不是一个真正的问题。没有存储列表元素的事实是由java.util.ArrayList实现造成的,该实现将底层对象数组标记为瞬态的。因此,微流在默认情况下不会持久化。但是,自定义类型处理程序可以解决这个问题。下面是一个示例,类FooTable的这种类型处理程序可能是这样的:

代码语言:javascript
复制
import one.microstream.X;
import one.microstream.persistence.binary.internal.AbstractBinaryHandlerCustomCollection;
import one.microstream.persistence.binary.types.Binary;
import one.microstream.persistence.types.PersistenceLoadHandler;
import one.microstream.persistence.types.PersistenceReferenceLoader;
import one.microstream.persistence.types.PersistenceStoreHandler;

public class FooTableTypeHandler extends AbstractBinaryHandlerCustomCollection<FooTable>
{
    //the fields to be stored are:
    //private final int tableNo from TableListImpl
    //private final int datatableNo from TableListImpl;
    //private String baz from FooTable
    //transient Object[] elementData from ArrayList
    
    //define the binary layout used for storing the class FooTable
    private static final long BINARY_OFFSET_TABLE_NO      = 0;
    private static final long BINARY_OFFSET_DATA_TABLE_NO = BINARY_OFFSET_TABLE_NO + Integer.BYTES;
    private static final long BINARY_OFFSET_BAZ           = BINARY_OFFSET_DATA_TABLE_NO + Integer.BYTES;
    private static final long BINARY_OFFSET_ELEMENTS      = BINARY_OFFSET_BAZ + Binary.referenceBinaryLength(1);
            
    protected FooTableTypeHandler()
    {
        super (FooTable.class,
            SimpleArrayFields(
                CustomField(int.class, "tableNo"),
                CustomField(int.class, "datatableNo"),
                CustomField(String.class, "baz")
                )
            );
    }
        
    @Override
    public void iterateLoadableReferences(final Binary data, final PersistenceReferenceLoader iterator)
    {
        //register all referenced items that need to be restored too
        data.iterateListElementReferences(BINARY_OFFSET_ELEMENTS, iterator);
        iterator.acceptObjectId(data.read_long(BINARY_OFFSET_BAZ));
    }
    
    @Override
    public void store(final Binary data, final FooTable instance, final long objectId, final PersistenceStoreHandler<Binary> handler)
    {
        //store items in the list
        data.storeIterableAsList(
            this.typeId()         ,
            objectId              ,
            BINARY_OFFSET_ELEMENTS,
            instance              ,
            instance.size()       ,
            handler
        );
        
        //store int values directly
        data.store_int(BINARY_OFFSET_TABLE_NO     , instance.getTableNo());
        data.store_int(BINARY_OFFSET_DATA_TABLE_NO, instance.getDatatableNo());
        
        //store a reference to the String field "baz" and handle the String itself, if needed
        data.store_long(BINARY_OFFSET_BAZ         , handler.apply(instance.getBaz()));
    }

    @Override
    public FooTable create(final Binary data, final PersistenceLoadHandler handler)
    {
        //read the int values
        //create empty instance
        return new FooTable(
            data.read_int(BINARY_OFFSET_TABLE_NO),
            data.read_int(BINARY_OFFSET_DATA_TABLE_NO));
    }
    
    private long getElementCount(final Binary data)
    {
        return data.getListElementCountReferences(BINARY_OFFSET_ELEMENTS);
    }
    
    @Override
    public void updateState(final Binary data, final FooTable instance, final PersistenceLoadHandler handler)
    {
        // instance must be cleared in case an existing one is updated
        instance.clear();
                
        //get all list elements
        data.collectObjectReferences(
            BINARY_OFFSET_ELEMENTS,
            X.checkArrayRange(this.getElementCount(data)),
            handler,
            e ->
                instance.add((String) e)
        );
        
        //get "baz"
        instance.setBaz((String) handler.lookupObject(data.read_long(BINARY_OFFSET_BAZ)));
    }

}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63309366

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档