Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Aerospike-如何在Java中反序列化包含对象的映射?_Java_Aerospike - Fatal编程技术网

Aerospike-如何在Java中反序列化包含对象的映射?

Aerospike-如何在Java中反序列化包含对象的映射?,java,aerospike,Java,Aerospike,我从Aerospike DB加载地图时遇到问题。当我获取记录并尝试打印它时,我得到了下面的错误 Main Key key = new Key( "test", "users", 2 ); Map<Integer, Widgets> map = new HashMap<>(); map.put(1, new Widgets(2, 2)); map.put(2, new Widgets(3, 0)); Bin bin = new Bin("widgets", map); cl

我从Aerospike DB加载地图时遇到问题。当我获取记录并尝试打印它时,我得到了下面的错误

Main

Key key = new Key( "test", "users", 2 );
Map<Integer, Widgets> map = new HashMap<>();
map.put(1, new Widgets(2, 2));
map.put(2, new Widgets(3, 0));
Bin bin = new Bin("widgets", map);
client.put( policy, key, bin );
存储在Aerospike中的数据

|                    | 2  | MAP('{1:AC ED 00 05 73 72 00 07 57 69 64 67 65 74 73 6F F3 7E F4 7F CD 1C 92 02 00 02 49 00 0A 63 6C 69 63 6B 43 6F 75 6E 74 49 00 09 76 69 65 77 43 6F 75 6E 74 78 70 00 00 00 02 00 00 00 02, 2:AC ED 00 05 73 72 00 07 57 69 64 67 65 74 73 6F F3 7E F4 7F  |
+--------------------+----+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
2 rows in set (0.098 secs)

小部件类

public class Widgets implements Serializable{
    private int viewCount;
    private int clickCount;
    // getters, setters and constructors here
}
数据被毫无问题地存储在数据库中,但它被存储为字节数组。我无法反序列化它

编辑

当我尝试打印地图时,确实会得到一个输出,但是当我尝试使用foreach时,它显示了一个错误

System.out.println(map); // works fine
输出

{1=Widgets@7e774085, 2=Widgets@3f8f9dd6} 

Aerospike始终将整数类型(short、int、long等)存储为数据库中的64位long。如果插入较短的数字类型,它将自动向上转换为较长的数字类型。这是为了支持没有较短数值类型的语言

因此,当您检索地图时,地图键将作为long返回。因此,此代码应替换您的检索代码:

        Record record = client.get(null, key); // using same key for testing
        Map<Long, Widgets> map2 = (Map<Long, Widgets>) record.getMap("widgets"); // here, I do get a map back... but its serialized 
        map2.forEach( (k,v) -> System.out.println(k));
通常,最好自己使用或序列化它们。例如,您可以将代码更改为:

package com.aerospike.play;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import com.aerospike.client.AerospikeClient;
import com.aerospike.client.Bin;
import com.aerospike.client.Key;
import com.aerospike.client.Record;

public class StackOverflowQuestion {
    public static class Widgets implements Serializable{
        private static final String VIEW_FIELD = "view";
        private static final String CLICK_FIELD = "click";

        private int viewCount;
        private int clickCount;

        public Widgets(int viewCount, int clickCount) {
                this.viewCount = viewCount;
                this.clickCount = clickCount;
        }
        public int getViewCount() {
            return viewCount;
        }
        public int getClickCount() {
            return clickCount;
        }

        @Override
        public String toString() {
                return String.format("{view: %d, count: %s}", viewCount, clickCount);
        }

        public Map<String, Object> asMap() {
                Map<String, Object> values = new HashMap<>();
                values.put(VIEW_FIELD, this.viewCount);
                values.put(CLICK_FIELD, this.clickCount);
                return values;
        }

        public static Widgets fromMap(Map<String, Object> map) {
                return new Widgets((int)(long)map.get(VIEW_FIELD), (int)(long)map.get(CLICK_FIELD));
        }
    }

    public static void main(String[] args) {
        AerospikeClient client = new AerospikeClient("172.28.128.4", 3000);
        Key key = new Key( "test", "users", 2 );
        Map<Integer, Map<String, Object>> map = new HashMap<>();
        map.put(1, new Widgets(2, 2).asMap());
        map.put(2, new Widgets(3, 0).asMap());
        Bin bin = new Bin("widgets", map);
        client.put( null, key, bin );

        Record record = client.get(null, key); // using same key for testing
        Map<Long, Map<String, Object>> map2 = (Map<Long, Map<String, Object>>) record.getMap("widgets"); 
        map2.forEach( (k,v) -> {
            Widgets w = Widgets.fromMap(v);
            System.out.printf("%d -> %s\n", k, w);
        });

        client.close();
    }
}
但存储在数据库中的数据使用的是本机类型:

aql> select * from test.users
*************************** 1. row ***************************
widgets: MAP('{1:{"view":2, "click":2}, 2:{"view":3, "click":0}}')

作为旁注,有更有效的方法来存储这些数据,如列表,但这种表示更具说明性。

当您得到异常时,回溯是什么?
aql> select * from test.users
*************************** 1. row ***************************
widgets: MAP('{1:AC ED 00 05 73 72 00 34 63 6F 6D 2E 74 69 6D 2E...
package com.aerospike.play;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import com.aerospike.client.AerospikeClient;
import com.aerospike.client.Bin;
import com.aerospike.client.Key;
import com.aerospike.client.Record;

public class StackOverflowQuestion {
    public static class Widgets implements Serializable{
        private static final String VIEW_FIELD = "view";
        private static final String CLICK_FIELD = "click";

        private int viewCount;
        private int clickCount;

        public Widgets(int viewCount, int clickCount) {
                this.viewCount = viewCount;
                this.clickCount = clickCount;
        }
        public int getViewCount() {
            return viewCount;
        }
        public int getClickCount() {
            return clickCount;
        }

        @Override
        public String toString() {
                return String.format("{view: %d, count: %s}", viewCount, clickCount);
        }

        public Map<String, Object> asMap() {
                Map<String, Object> values = new HashMap<>();
                values.put(VIEW_FIELD, this.viewCount);
                values.put(CLICK_FIELD, this.clickCount);
                return values;
        }

        public static Widgets fromMap(Map<String, Object> map) {
                return new Widgets((int)(long)map.get(VIEW_FIELD), (int)(long)map.get(CLICK_FIELD));
        }
    }

    public static void main(String[] args) {
        AerospikeClient client = new AerospikeClient("172.28.128.4", 3000);
        Key key = new Key( "test", "users", 2 );
        Map<Integer, Map<String, Object>> map = new HashMap<>();
        map.put(1, new Widgets(2, 2).asMap());
        map.put(2, new Widgets(3, 0).asMap());
        Bin bin = new Bin("widgets", map);
        client.put( null, key, bin );

        Record record = client.get(null, key); // using same key for testing
        Map<Long, Map<String, Object>> map2 = (Map<Long, Map<String, Object>>) record.getMap("widgets"); 
        map2.forEach( (k,v) -> {
            Widgets w = Widgets.fromMap(v);
            System.out.printf("%d -> %s\n", k, w);
        });

        client.close();
    }
}
1 -> {view: 2, count: 2}
2 -> {view: 3, count: 0}
aql> select * from test.users
*************************** 1. row ***************************
widgets: MAP('{1:{"view":2, "click":2}, 2:{"view":3, "click":0}}')