使用父键

时间:2016-06-14 13:50:56

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

我编写了一段代码,通过使用提供的父密钥过滤实体,从google数据存储中提取实体。当我运行代码时,我得到java.lang.IllegalArgumentException

我知道问题在于我创建父密钥的方式,您能否指导我如何有效地为此用例创建父密钥?

我在Myservice.java第8行

中收到以下异常
    Method threw 'java.lang.IllegalArgumentException' exception 
- Class hierarchy for class java.lang.Class has no @Entity annotation

Appengine v1.9.36, Objectify v5.1.7, JDK v1.7

以下是示例代码

import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Cache;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;

    @Entity
    @Cache
    public class ParentEntity {

        @Id
        Long id;

        String name;

        String value;

        public static Key<ParentEntity> getKey(Long id){
            return Key.create(ParentEntity.class, id);
        }

        public Long getId() {
            return id;
        }

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

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }
    }

另一个实体类

import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Cache;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Parent;

@Entity
@Cache
public class ChildEntity {

    @Id
    Long id;

    @Parent Key<ParentEntity> application;

    String city;

    public static Key<ChildEntity> getKey(Long id){
        return Key.create(Key.create(ParentEntity.class), ChildEntity.class, id);
    }

    public Long getId() {
        return id;
    }

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

    public Key<ParentEntity> getApplication() {
        return application;
    }

    public void setApplication(Key<ParentEntity> application) {
        this.application = application;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }
}

使用Objectify获取实体的ServiceLaver

import java.util.List;
import com.googlecode.objectify.ObjectifyService;

public class MyService{

    public List<ChildEntity> filterByID(Long id){
        return ObjectifyService.ofy().load().type(ChildEntity.class)
            .filterKey(ChildEntity.getKey(id)).first().now();
    }
}

1 个答案:

答案 0 :(得分:4)

更改您的ParentEntity方法:

 public String getWebSafeKey(){
                    return Key.create(ParentEntity.class, id).getString();
            }

为:

public List<ChildEntity> filterByID(Long id){
        return ObjectifyService.ofy().load().type(ChildEntity.class)
            .filterKey(ChildEntity.getKey(id)).first().now();
    }

现在,当您插入父实体时,它将为您提供该父实体的网络安全密钥。每当您想要访问此插入的父实体时,请使用此websafe密钥。

改变之后:

public List<ChildEntity> filterByID(String parentWebSafeKey){
        return ObjectifyService.ofy().load().type(ChildEntity.class)
            .ancestor(Key.create(parentWebSafeKey)).first().now();
    }

要:

child_entity.application = Ref.create(parent_entity_key);

在使用以下方法创建子实体时,不要忘记在ParentEntity和ChildEntity之间创建关系:

AssetManager assetManager = getActivity().getAssets();
    File file = new File(Environment.getExternalStorageDirectory()
            + "/tesseract/tessdata", lang + ".traineddata");
    if (!(file.exists())) {
        try {
            InputStream in = assetManager.open("tessdata/" + lang
                    + ".traineddata");
            String sdCardPath = Environment.getExternalStorageDirectory()
                    + "/tesseract/tessdata";
            File outFile = new File(sdCardPath + "/", lang + ".traineddata");
            OutputStream out = new FileOutputStream(outFile);
            copyFile(in, out);
            in.close();
            in = null;
            out.flush();
            out.close();
            out = null;
        } catch (IOException e) {
            Log.e("tag", "Failed to copy asset file: " + lang
                    + ".traineddata", e);
        }
    }