【问题标题】:Objectify - save order of Ref<?>-sObjectify - 保存 Ref<?>-s 的顺序
【发布时间】:2018-04-26 00:33:06
【问题描述】:

我有一个系统,我试图最小化 Datastore 写入次数(谁不会?),同时使用祖先关系。考虑以下简化类:

public class Ancestor {
    @Id
    private String id;
    private String field;
    private Ref<Descendant> descendantRef;
    public Descendant getDescendant() {
        return this.descendantRef.get();
    }
    public void setDescendant(Descendant des) {
        this.descendantRef = Ref.create(des);
    }
}

public class Descendant {
    @Id
    private String id;
    private String field;
    @Parent
    private Key parent;
}

我的问题:即使我设置了后代 ref,在保存 Ancestor 实体时,也会保存 null,但如果我也保存后代,Objectify 会抱怨 Attempted to save a null entity

我的问题:我收集到 Objectify 使用 @Load 注释优化了 get() 操作的顺序,所以有没有办法让它在 save() 操作上也做同样的事情,所以到时候Ancestor 正在发送到 Datastore,Descendant ref 是否已正确填充?

提前感谢您的任何建议!

【问题讨论】:

  • 您是在问如何在保存多个 Ancestor 时优化 descendantRef 的 save() 操作吗?
  • @Ajeet 更像是如果有办法只在祖先上调用save(),并让 Objectify 优化类似于加载图的“保存图”并首先保存 Descendant,构造 Ref ,并以此拯救祖先。这很可能是不可能的。除此之外,如果有办法自动构造一个descendantRef,及时将Ancestor与ref一起保存......

标签: google-app-engine objectify


【解决方案1】:

如果您将 null 值传递给 save() 方法,Objectify 只会抱怨您 Attempted to save a null entity

这不是操作顺序问题。 FWIW,Objectify 和底层数据存储都不提供任何类型的引用完整性检查。先保存哪个并不重要。

【讨论】:

    【解决方案2】:

    你可以像这样隐藏这个实现:

    public Descendant getDescendant() {
        // You probably don't want to break your code on null descendantRef
        if (this.descendantRef != null) {
            return this.descendantRef.get();
        }
        return null;
    }
    
    public void setDescendant(Descendant des) {
        // Insert if this des have never been insert
        if (getDescendant() != null) {
            new DescendantEndpoint().insert(des);
        }
        // You probably don't want to break your code on null des
        if (des != null) {
            this.descendantRef = Ref.create(des);
        }
    }
    

    通过这种方式,您不必处理将要创建的每个端点上的每次插入 ref。尽管如此,此方法并未针对批量插入进行优化,因为它将在每个单独的数据存储连接上插入。

    为此,您可以执行以下操作:

    private Object bulkInsertAncestor(ArrayList<Ancestor> list){
            ArrayList<Descendant> descendantArrayList = //get descendant list
            // You should do all this inside a transaction
            new DescendantEndpoint().bulkInsertDescendant(descendantArrayList);
            return ofy().save().entities(list);
        }
    

    【讨论】:

    • 另外,请确保在您的应用引擎应用程序中,您的每个实体端点只有一个 insert 和 bulkInsert API
    • 如果您有任何疑问或疑问,请告诉我。我正在使用 objectify 和 app-engine 开发应用程序。我正在尝试我自己的方法。
    猜你喜欢
    • 1970-01-01
    • 2012-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-28
    • 2017-03-30
    • 1970-01-01
    相关资源
    最近更新 更多