投影查询:如何使用 JPA 为 AppEngine 中的新实体加载原始字符串?
Posted
技术标签:
【中文标题】投影查询:如何使用 JPA 为 AppEngine 中的新实体加载原始字符串?【英文标题】:Projection Queries: How to load raw String using JPA for new Entity in AppEngine? 【发布时间】:2013-10-18 14:23:55 【问题描述】:如何在 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 上创建一个新的空表并不明显。
【问题讨论】:
如果您不想创建 AdminUser 类,请不要引用。首先阅读 JPA 规范和关于 JPQL 的部分,然后参考您实际拥有的类。为什么不提你有什么课?以及您要选择该课程的哪个领域? @DataNucleus 这非常无用。你看过示例链接吗? 读者的角色是制作 cmets,以便提问的人实际上提出了一个可以理解的问题;这目前不是。如果你使用 JPA,你有一些类、一些元数据、一些持久性代码、一些查询。你想“加载字符串列表”......它在哪里?您不说,而是继续创建“空表”。澄清你的问题是第一步 @DataNucleus 抱歉,我无法帮助您进行阅读理解。我的问题就足够了。您提出的所有问题都存在。 【参考方案1】:GAE Datastore 是一个无模式 NoSQL 数据库。没有桌子。只有实体必须具有种类、ID 并且可以具有任意一组属性。
您可以使用Datastore via JPA API,而不是low-level untyped entities,为您提供漂亮的类型化Java 类。
【讨论】:
是的,我已经读过,但它没有说明如何创建一个空表/实体。在创建要插入的行之前,我需要先从表中读取。通常对于Web应用程序,您可以直接进入数据库并创建一个表。您是说 Google AppEngine 不支持创建表/实体来引导 Web 应用程序吗? 没错,没有架构,所以没有要定义的表。 GAE 上有超过 10 万个应用程序,所以他们一定做对了,对吧? 另外,您的 JPA 异常似乎是由于您没有定义AdminUser
类。这与 AppEngine 或其数据存储无关。 JPA 是一个帮助库,将数据从数据库映射到 Java 类。
我会说,这个大洞应该是你的礼仪,而不是谷歌的 appengine 设计。【参考方案2】:
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()
【讨论】:
以上是关于投影查询:如何使用 JPA 为 AppEngine 中的新实体加载原始字符串?的主要内容,如果未能解决你的问题,请参考以下文章
Spring JPA - “java.lang.IllegalArgumentException:投影类型必须是接口!” (使用本机查询)