如何序列化protobuf中的反向关系

时间:2015-08-06 19:25:39

标签: java serialization protocol-buffers reverse

我有以下原型文件

message Person {

    // ID
    required int32 id = 1;

    // name
    required string name = 2;

    // email
    optional string email = 3;

    // tasks
    repeated Task tasks = 4;
}

message Task {
    //ID
    required int32 id = 1;

    //owner
    optional Person owner =2;

}

人有任务列表,这是一对多的关系。 在任务中,我设置与人的反向关系,这是一对一的关系。

我的问题是:当我在人物对象中构建任务时,如何序列化与当前人物的反向关系,因为人物对象尚未构建。请参阅 ???? (问号)部分在以下代码段中。 我有以下代码序列化。

PersonMsg.Person.Builder personBuilder = PersonMsg.Person.newBuilder();  
    personBuilder.setId(1);  
    personBuilder.setName("Alex");  
    personBuilder.setEmail("alex@gmail.com");  
    personBuilder.addTasks(PersonMsg.Task.newBuilder()
                            .setId(11)
                            .setOwner("??????"));
    personBuilder.addTasks(PersonMsg.Task.newBuilder()
                            .setId(12)
                            .setOwner("???????"));
    PersonMsg.Person xxg = personBuilder.build(); 

提前致谢!

2 个答案:

答案 0 :(得分:2)

这基本上是一个循环依赖,你需要解决它,否则程序不会编译。

由于PersonTask的成员,TaskPerson之间已有合成。基本上,您不需要将TaskPerson关联起来,因为现有链接已经存在。

如果你真的需要一个双链接,我建议使用一个消息引用(如外键)到Person对象。

message Task {
    //ID
    required int32 id = 1;
    //owner
    optional int32 ownerId =2; //which is the owner Person id.

}

答案 1 :(得分:2)

这不起作用,因为协议缓冲区不支持指针。 tasks的{​​{1}}字段不存储指向任务的指针,它存储实际任务。 Person的{​​{1}}字段不存储指向某个人的指针,它会存储一个完整的owner。您不能拥有两个具有相同Task的{​​{1}},因为这需要指针。

这意味着Protobuf消息始终是一棵树。这与Java一般不同,其中对象形成任意图形,可能具有循环。

解决方案是让Person字段Task存储一个人的 ID ,而不是存储完整的owner。然后,您的代码需要知道如何查找给定ID的owner