DataStore:在给定父级的事务中查询实体时出现问题

时间:2017-03-26 13:29:26

标签: google-app-engine google-cloud-datastore objectify

实体是这个抽象类的所有子类,它一直工作到最近它返回一个空结果,这里是它工作的代码,然后是工作的代码

public abstract AbstractParentEntity{
    @Index @Parent private Ref<T> parentKey;

    protected void setParent(Class<T> parentClazz, T parent){

       Key<T> key = Key.create(parentClazz, parent.getGuid());

      this.parentKey = Ref.create(key);
    }
}

它查询实体:

Key<V> parent = Key.create(parentClazz, parentKey);

Query<T> query = ofy().load().type(clazz).ancestor(ref);
QueryResultIterator<T> iterator = query.iterator();

有效的代码:

public abstract AbstractParentEntity{
    @Index @Parent private Ref<T> parentKey;

    protected void setParent(Class<T> parentClazz, T parent){
       this.parentKey = Ref.create(parent);
    }
 }

它查询实体:

Ref<V> ref = createRef(parent);
Query<T> query = ofy().load().type(clazz).ancestor(ref);
QueryResultIterator<T> iterator = query.iterator();

我无法使用有效的方法,因为它基本上会更改父级,并导致实体松散。

我使用的数据片段(忽略@Id和其他setter和getter)

class AncesorModel{
}

class ParentModel extends AbstractParentEntity<AncesorModel>{

}

class ChildModel extends AbstractParentEntity<ParentModel>{

}
// create new AncesorModel object and save it in DS
// create new ParentModel object that has the AncesorModel as parent and save it in DS
// create several ChildModel objects that have ParentModel as parent and save it in DS
//query for ChildModel by using the AncesorModel 

Key<V> ancKey = Key.create(AncesorModel.class , ancId);

Query<T> query = ofy().load().type(ChildModel.class).ancestor(ancKey);
QueryResultIterator<ChildModel> iterator = query.iterator();

知道为什么使用第一个方法会返回空结果吗?

这是一个干净的例子:

@Entity
public class ChildModel {

    @Id
    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @Parent
    private Ref<ParentModel> par;
    public ParentModel getPar(){
        return this.par.get();
    }

    public void setPar(ParentModel par){
        Key<ParentModel> key = Key.create(ParentModel.class, par.getId());
        this.par = Ref.create(key);
    }
}

@Entity
public class ParentModel {

    @Id
    private String id;

    @Parent 
    private Ref<AncesorModel> anc;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public AncesorModel getAnc(){
        return this.anc.get();
    }

    public void setAnc(AncesorModel anc){
        Key<AncesorModel> key = Key.create(AncesorModel.class, anc.getId());
        this.anc = Ref.create(key);
    }
}

@Entity
public class AncestorModel{

    @Id
    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}

AncestorModel anc = new AncestorModel();
anc.setId(generateId());
ofy().save().entity(anc).now();

anc = ofy().load().key(Key.create(AncestorModel.class, anc.getId())).now();

ParentModel par = new ParentModel();
par.setAnc(anc);
par.setId(generateId());
ofy().save().entity(par).now();

Key<AncestorModel> ancKey = Key.create(AncestorModel.class, anc.getId());
par = ofy().load().type(ParentModel.class).parent(ancKey).id(par.getId()).now();

ChildModel child1 = new ChildModel();
child1.setId(generateId());
child1.setPar(par);
ofy().save().entity(child1).now();

ChildModel child2 = new ChildModel();
child2.setId(generateId());
child2.setPar(par);
ofy().save().entity(child2).now();

ChildModel child3 = new ChildModel();
child3.setId(GUIDUtils.generateGuid());
child3.setPar(par);
ofy().save().entity(child3).now();

ancKey = Key.create(AncestorModel.class, anc.getId());

//empty result
List<ChildModel> childs = ofy().load().type(ChildModel.class).ancestor(ancKey).list();

//3 entities in the result
childs = ofy().load().type(ChildModel.class).list();

1 个答案:

答案 0 :(得分:1)

请阅读有关密钥的部分:

https://github.com/objectify/objectify/wiki/Concepts

父母是实体身份的一部分;你永远不能改变它就像你永远不能改变身份。也许您想要使用单独的索引字段?

另外:您不需要@Index个父字段。