Search code examples
google-app-enginejpagoogle-cloud-sql

using google app engine with JPA and cloud sql not returning any records using endpoints


I have an Android project and an app engine connected project. I am using the following: JPA v2, App Engine 1.7.6, Java 1.7 compiler, Eclipse 4.2 Juno, EclipseLink 2.4.x

I am using Cloud sql db. I am able to connect successfully in the JPA and DB Persective window and query data back ok. I have set up my app engine to have the SQL Development to be connected to my CLOUD Sql db.

I have one table defined as follows:

CREATE Table Test(codeid varchar(3) NOT NULL,codedesc varchar(20) NOT NULL,PRIMARY KEY (codeid));

The Entity class is as follows:

 import java.io.Serializable;
    import javax.persistence.*;



    @Entity
    public class Test implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    private String codeid;

    private String codedesc;

    public Test() {
    }

    public String getCodeid() {
    return this.codeid;
    }

    public void setCodeid(String codeid) {
this.codeid = codeid;
    }

    public String getCodedesc() {
        return this.codedesc;
    }

    public void setCodedesc(String codedesc) {
        this.codedesc = codedesc;
    }
    }

the endpoint class is as follows:

 @Api(name = "testendpoint" , version = "v1")
    public class TestEndpoint {

    /**
     * This method lists all the entities inserted in datastore.
     * It uses HTTP GET method and paging support.
     *
     * @return A CollectionResponse class containing the list of all entities
     * persisted and a cursor to the next page.
     */
    @ApiMethod(    httpMethod = "GET",    name = "listtest.list",     path = "ch/list")
    @SuppressWarnings({ "unchecked", "unused" })
    public CollectionResponse<Test> listTest(
            @Nullable @Named("cursor") String cursorString,
            @Nullable @Named("limit") Integer limit) {

        EntityManager mgr = null;
        Cursor cursor = null;
        List<Test> execute = null;

        try {
            mgr = getEntityManager();
            Query query = mgr.createQuery("select x from Test x");
            if (cursorString != null && cursorString != "") {
                cursor = Cursor.fromWebSafeString(cursorString);
                query.setHint(JPACursorHelper.CURSOR_HINT, cursor);
            }

            if (limit != null) {
                query.setFirstResult(0);
                query.setMaxResults(limit);
            }

            execute = (List<Test>) query.getResultList();
            cursor = JPACursorHelper.getCursor(execute);
            if (cursor != null)
                cursorString = cursor.toWebSafeString();

            // Tight loop for fetching all entities from datastore and accomodate
            // for lazy fetch.
            for (Test obj : execute);
        } 
        finally 
        {
            mgr.close();
        }

            return CollectionResponse.<Test> builder().setItems(execute).setNextPageToken       (cursorString).build();
    }

    private boolean containsCodeheader(Test test) {
        EntityManager mgr = getEntityManager();
        boolean contains = true;
        try {
            Test item = mgr
                    .find(Test.class, test.getCodeid());
            if (item == null) {
                contains = false;
            }
        } finally {
            mgr.close();
        }
        return contains;
    }

        private static EntityManager getEntityManager() {
        return EMF.get().createEntityManager();
    }

    }

persistence.xml looks as follows:

<?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_2_0.xsd" version="2.0">

    <persistence-unit name="transactions-optional" transaction-type="RESOURCE_LOCAL">
        <provider></provider>
        <class>com.testApp.Test</class>
        <properties>
            <property name="datanucleus.NontransactionalRead" value="true"/>
            <property name="datanucleus.NontransactionalWrite" value="true"/>
            <property name="datanucleus.ConnectionURL" value="appengine"/>

What I am trying to do is run my endpoint to get a list of records back . I When I run the following I dont get any errors in the console.

localhost:8888/_ah/api/testendpoint/v1/ch/list

I get the follwoing in the Google Chrome when I know there are records in my table.

 {
    "items" : [ ]
  }

Please let me know if you need more info.

I have carried out further testing and found my above example works for another test app engine project I created before from scratch. A difference I have found is, when I run the broken app engine locally I get the following warning in the Console window which I dont in the working test app:

The backing store, \war\WEB-INF\appengine-generated\local_db.bin, does not exist. It will be created.


Solution

  • Well I am happy to report that I found the answer to this issue. Turns out I was doing everything correctly. The only thing I had to do was take the following line out of persistence.xml file:

    <property name="datanucleus.ConnectionURL" value="appengine"/>
    

    I already had the following set in the file:

    <property name="javax.persistence.jdbc.driver" value="com.google.appengine.api.rdbms.AppEngineDriver"/>
    <property name="javax.persistence.jdbc.url" value="jdbc:google:rdbms://Your db connection/databasename"/>.