投影查询:如何使用JPA为AppEngine中的新实体加载原始字符串?

时间:2013-10-10 17:25:58

标签: java google-app-engine jpa entity google-cloud-datastore

如何在AppEngine中为全新的,空的,不存在的表加载字符串列表?我试着效仿这个例子:

http://www.objectdb.com/java/jpa/query/jpql/select#Projection_of_Path_Expressions_

但它给了我一个错误:

  

引起:javax.persistence.PersistenceException:尚未解析用于查询的类AdminUser。检查查询和任何导入/别名规范

     

引起:org.datanucleus.exceptions.ClassNotResolvedException:尚未解析用于查询的类AdminUser。检查查询和任何导入/别名规范

以下是代码:

public java.util.List<String> getAdmin() {
    EntityManager em = EMF.get().createEntityManager();
    try {
        TypedQuery<String> tq = em.createQuery("select au.email from AdminUser as au", String.class);
        return tq.getResultList();  ///// <=== EXCEPTION

我实际上并不想使用AdminUser类。我只想要单列字符串。如何在AppEngine上创建一个新的空表并不明显。

2 个答案:

答案 0 :(得分:1)

GAE数据存储区是一个无模式的NoSQL数据库。没有桌子。只有必须具有种类,id并且可以具有任意属性集的实体。

您可以使用Datastore via JPA API为您提供不错的类型Java类,而不是low-level untyped entities

答案 1 :(得分:-1)

AppEngine不支持JPA原始基元查询,如示例链接中所示。我必须直接使用DatastoreService API。这是我试过的。需要一些清洁,因为许多事情都不起作用,但确实如此。

    public java.util.List<String> getAdmin() {
        log.info("getAdmin()");

        // AppEngine does not support strong consistency... will frequently return stale results. Setting read policy won't work.
        // Construct a read policy for strong consistency
        ReadPolicy policy = new ReadPolicy(ReadPolicy.Consistency.STRONG);
        // Set the read policy
        DatastoreServiceConfig consistentConfig = DatastoreServiceConfig.Builder.withReadPolicy(policy);
        // Get Datastore service with the given configuration
        DatastoreService datastoreService =  DatastoreServiceFactory.getDatastoreService(consistentConfig);

        com.google.appengine.api.datastore.Query query  = new com.google.appengine.api.datastore.Query("AdminUser");
//      DatastoreService datastoreService = DatastoreServiceFactory.getDatastoreService();
        java.util.List<Entity> events = datastoreService.prepare(query).asList(FetchOptions.Builder.withDefaults());
        ArrayList<String> al = new ArrayList<String>();
        for(Entity entity: events) {
            String s = entity.getProperty("email").toString();
            al.add(s);
        }
        if(true) return al; 


        @SuppressWarnings("unused")
        EntityManager em = EMF.get().createEntityManager();
        try {
            TypedQuery<String> tq = em.createQuery("select au.email from AdminUser as au", String.class);
            return tq.getResultList();
        } catch (ClassNotResolvedException | javax.persistence.PersistenceException cnre) {
            // catch the exception because AppEngine DataStore has no way to create a new empty Entity table.
            log.warning("AdminUser entity does not exist or is empty.");
            return new java.util.ArrayList<String>();
        } finally {
            em.close(); 
        }

//      log.info("getAdmin(): al.size(): " + al.size());
    }


    public void setAdmin(java.util.List<String> admin) {
        log.info("setAdmin(), admin.size():"+admin.size());

        // delete all AdminUsers
        com.google.appengine.api.datastore.Query query  = new com.google.appengine.api.datastore.Query("AdminUser");
        DatastoreService datastoreService = DatastoreServiceFactory.getDatastoreService();
        java.util.List<Entity> events = datastoreService.prepare(query).asList(FetchOptions.Builder.withDefaults());
        for(Entity entity: events) {
            datastoreService.delete(entity.getKey());
        }


//      EntityManager em = EMF.get().createEntityManager();
//      Query q = em.createQuery("delete from AdminUser");
//      q.executeUpdate();


//      DatastoreService datastoreService = DatastoreServiceFactory.getDatastoreService();
        for (String s: admin) {
            log.info("creating AdminUser Entity...");
            Entity e = new Entity("AdminUser");
            e.setProperty("email", s);
            datastoreService.put(e);    
        }
        // Must wait for Datastore to actually write records. Ignores consistency even with strong consistency set.
        // this doesn't even work sometimes...
        //try { Thread.sleep(5000); } catch (InterruptedException e) {}

//      EntityManager em = EMF.get().createEntityManager();
//      for (String s: admin) {
//          Entity e = new Entity("AdminUser");
//          e.setProperty("email", s);
//          em.persist(e);
//      }
//      em.close();

    } // setAdmin()