【问题标题】:DataNucleus on AppEngine not returning any resultsAppEngine 上的 DataNucleus 不返回任何结果
【发布时间】:2016-06-13 12:57:11
【问题描述】:

我几乎尝试了所有方法,但在以下目标平台上运行简单的 SQL 查询时没有收到任何结果:Google AppEngine + Google Cloud SQL 数据存储使用 DataNucleus(全部在 Google Cloud Platform 上)。 我已经部署了一个基本的 Java Servlet 并设置了一个简单的 MySql 表。这是详细信息。最令人沮丧的是,我不知道如何获取更多信息以进行进度。因此,非常感谢您的帮助。同样,没有错误,只是结果集中没有结果。

数据库

当然,我 100% 确定表中有数据。我的数据库(MySql)在架构“vicparkhoney”中有下表:

CREATE TABLE `mytable` ( `name` varchar(255) DEFAULT NULL);

下面的查询,直接在MySql workbench中输入会得到两个结果:

SELECT * FROM vicparkhoney.mytable;

结果:

name
===========
Name1
Name2

(对于那些想知道我是否已经提交插入的人来说,即使在几次重新连接之后......)

这不会让您感到惊讶,以下查询返回一个结果:

SELECT * FROM vicparkhoney.mytable n WHERE n.name = 'Name1';

name
===========
Name1

Java 代码

通过 DataNucleus 运行 JPA 查询时,我没有得到相同的结果。这是我的 Servlet 代码:

EntityManagerFactory emf = Persistence.createEntityManagerFactory("transactions-optional");
EntityManager em = emf.createEntityManager();
Query q = em.createQuery("select n from MyTable n where n.name = 'Name1'");
List results = q.getResultList();
Iterator iter = results.iterator();
MyTable n = null;
while (iter.hasNext()) {
    n = (MyTable)iter.next();
}
em.close();

这是实体类的MyTable 代码:

package com.vicparkhoney.backend.bean;
import javax.persistence.*;

@Entity
@Table( name = "mytable" )
public class MyTable {

    @Basic
    @Id
    private String name;

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }
}

JPA 配置

这是我的 persistence.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"         
    version="1.0">

<persistence-unit name="transactions-optional">
    <provider>org.datanucleus.api.jpa.PersistenceProviderImpl</provider>
    <class>com.vicparkhoney.backend.bean.MyTable</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
        <property name="datanucleus.mapping.Schema" value="vicparkhoney"/>
        <property name="datanucleus.NontransactionalRead" value="true"/>
        <property name="datanucleus.NontransactionalWrite" value="true"/>
        <property name="datanucleus.ConnectionURL" value="appengine"/>
    </properties>
</persistence-unit>
</persistence>

日志

我想知道是否有办法在日志中获取有关 DataNucleus 正在运行的确切 SQL 的更多信息。我用过:

DataNucleus.level=FINEST
DataNucleus.Datastore.Native=FINEST

日志:

20:08:55.937
org.datanucleus.query.JPQLSingleStringParser <init>: JPQL Single-String with "select n from MyTable n where n.name = 'Name1'"
20:08:56.141
org.datanucleus.store.query.AbstractJPQLQuery compileInternal: JPQL Query : Compiling "SELECT n FROM MyTable n WHERE n.name = 'Name1'"
20:08:56.339
org.datanucleus.store.query.AbstractJPQLQuery compileInternal: JPQL Query : Compile Time = 198 ms
20:08:56.340
org.datanucleus.store.query.AbstractJPQLQuery compileInternal: QueryCompilation:
  [from:ClassExpression(alias=n)]
  [filter:DyadicExpression{PrimaryExpression{n.name}  =  Literal{Name1}}]
  [symbols: n type=com.vicparkhoney.backend.bean.MyTable]
20:08:56.342
com.google.appengine.datanucleus.query.JPQLQuery performExecute: JPQL Query : Executing "SELECT n FROM MyTable n WHERE n.name = 'Name1'" ...
20:08:56.342
com.google.appengine.datanucleus.MetaDataValidator validate: Performing appengine-specific metadata validation for com.vicparkhoney.backend.bean.MyTable
20:08:56.344
com.google.appengine.datanucleus.MetaDataValidator validate: Finished performing appengine-specific metadata validation for com.vicparkhoney.backend.bean.MyTable
20:08:56.628
org.datanucleus.store.StoreDataManager registerStoreData: Managing Persistence of Class : com.vicparkhoney.backend.bean.MyTable [Table : com.vicparkhoney.backend.bean.MyTable, InheritanceStrategy : new-table]
20:08:57.342
com.google.appengine.datanucleus.query.JPQLQuery performExecute: Query compiled as : Kind=com.vicparkhoney.backend.bean.MyTable Filter : __key__=mytable("Name1") [QUERY-TYPE=NORMAL]
20:08:57.439
com.google.appengine.datanucleus.query.DatastoreQuery performExecute: Executing query in datastore for SELECT n FROM MyTable n WHERE n.name = 'Name1'
20:08:58.930
com.google.appengine.datanucleus.DatastoreConnectionFactoryImpl$DatastoreManagedConnection <init>: Created ManagedConnection using DatastoreService = com.google.appengine.api.datastore.DatastoreServiceImpl@9355b6
20:08:58.937
org.datanucleus.store.connection.ConnectionManagerImpl allocateConnection: Connection added to the pool : com.google.appengine.datanucleus.DatastoreConnectionFactoryImpl$DatastoreManagedConnection@56c36c for key=org.datanucleus.ObjectManagerImpl@15f65a1 in factory=ConnectionFactory:nontx[com.google.appengine.datanucleus.DatastoreConnectionFactoryImpl@3817d7]
20:08:58.938
com.google.appengine.datanucleus.query.JPQLQuery performExecute: JPQL Query : Execution Time = 2596 ms
20:08:59.150
org.datanucleus.store.connection.ConnectionManagerImpl closeAllConnections: Connection found in the pool : com.google.appengine.datanucleus.DatastoreConnectionFactoryImpl$DatastoreManagedConnection@56c36c for key=org.datanucleus.ObjectManagerImpl@15f65a1 in factory=ConnectionFactory:nontx[com.google.appengine.datanucleus.DatastoreConnectionFactoryImpl@3817d7] but owner object closing so closing connection
20:08:59.220
org.datanucleus.store.connection.ConnectionManagerImpl$1 managedConnectionPostClose: Connection removed from the pool : com.google.appengine.datanucleus.DatastoreConnectionFactoryImpl$DatastoreManagedConnection@56c36c for key=org.datanucleus.ObjectManagerImpl@15f65a1 in factory=ConnectionFactory:nontx[com.google.appengine.datanucleus.DatastoreConnectionFactoryImpl@3817d7]
20:08:59.220
org.datanucleus.ObjectManagerImpl disconnectObjectProvidersFromCache: Level 1 Cache cleared
20:08:59.223
org.datanucleus.ObjectManagerImpl close: Object Manager "org.datanucleus.ObjectManagerImpl@15f65a1" closed

【问题讨论】:

  • Neil,关于 URL=appengine,我只需点击此链接:cloud.google.com/appengine/docs/java/datastore/jpa/overview 我将使用 appengine-web.xml 更新原始帖子以显示 MySql URL。
  • 我做了一个小的 sql 练习,并且在没有 DataNucleus 的情况下工作。我更改了 persistence.xml,使其包含:&lt;property name="datanucleus.ConnectionURL" value="jdbc:google:mysql://[projid:db-instance]/[dbname]?user=root"/&gt;。我现在收到以下错误(我看到你评论了其他有同样问题的人)There is no available StoreManager of type "jdbc". Make sure ... put the relevant DataNucleus store plugin in your CLASSPATH and if defining a connection via JNDI or DataSource you also need to provide ... property "datanucleus.storeManagerType" - 有什么想法吗?
  • 请接受答案,或发布您认为它没有回答问题的原因

标签: google-app-engine google-cloud-endpoints google-cloud-sql datanucleus


【解决方案1】:

“Google AppEngine” 最初只带有自己的“NoSQL”数据库,称为 GAE/Datastore。 Google 提供了他们自己的 DataNucleus 插件来允许对此进行持久化,称为 datanucleus-appengine.jar。此数据存储区需要将 datanucleus.ConnectionURL 设置为 appengine。如果使用它,那么您将使用非常旧的 jar,因为 Google 插件 jar 不适用于最近的任何东西。

他们随后添加了 “Google CloudSQL”,它带有一个 MySQL/MariaDB 数据库。 DataNucleus 项目提供了自己的插件来持久化,称为 datanucleus-rdbms.jar。使用它,您可以使用最近的 DataNucleus 项目 jar。此数据存储要求将datanucleus.ConnectionURL 设置为以jdbc 开头的内容。

您当前使用的是 GAE/Datastore 数据库而不是 MySQL(因此您在 MySQL 中手动运行的测试都很好,但您还没有配置持久层来使用它!)。您需要修复 ConnectionURL 并确保您的 CLASSPATH 中有 datanucleus-rdbms jar。此外,请阅读相关站点的文档(Google AppEngine,如果想要使用 GAE/Datastore 数据库,或者DataNucleus itself,如果想要持久化到 mySQL)。

【讨论】:

    猜你喜欢
    • 2015-04-23
    • 2012-01-04
    • 2023-04-01
    • 2017-12-28
    • 2017-12-09
    • 2020-10-03
    • 2017-03-19
    • 2017-05-20
    • 2012-08-08
    相关资源
    最近更新 更多