Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    DataSource.get("course_DataSource") is returning null

    I'm running smartgwtee-2.3 with GAE 1.3.6 and trying to get a couple of data sources set up. I'm using com.isomorphic.jpa.GAEJPADataSource as the data store.

    I'm just trying to get a simple ListGrid set up with this data. The problem seems to be that DataSource.get("course_DataSource") is returning null. Is there a way to get an error code or otherwise find out WHY it's returning null?

    I'm translating this code almost directly from the country and city example included (ds-gae). I've probably missed some bit of the translation. Are there any small things that are easy to forget about setting up DataSources?

    Thanks ~

    Here's my code for the entry point:

    Code:
    	public void onModuleLoad()
    	{		
            final DataSource standardDS = DataSource.getDataSource("course_DataSource");
            final ListGrid lg = new ListGrid();
            lg.setDataSource(standardDS);
            lg.draw();
            
            IButton addButton = new IButton("Add a record");
            addButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {
    
    			@Override
    			public void onClick(
    							com.smartgwt.client.widgets.events.ClickEvent event)
    			{
    				lg.startEditingNew();
    			}
            });
            
            addButton.draw();        
    	}
    Here's course_DataSource.ds.xml:

    Code:
    <DataSource
        ID="course_DataSource"
        serverConstructor="com.isomorphic.jpa.GAEJPADataSource"
        beanClassName="com.longfellow.egmockup.server.Course"
        >
        <fields>
            <field name="courseID"     type="text"             hidden="true"   primaryKey="true" />
            <field name="courseName"   type="text"             title="Course Title" required="true"   />
            <field name="standards"        type="standard_DataSource"  title="Standards"  multiple="true"
                   javaClass="com.longfellow.egmockup.server.Standard"/>
        </fields>
    </DataSource>
    and here's Course.Java

    Code:
    package com.longfellow.egmockup.server;
    
    import java.io.Serializable;
    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.persistence.CascadeType;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.OneToMany;
    
    import org.datanucleus.jpa.annotations.Extension;
    
    @Entity
    public class Course implements Serializable
    {
    	@Id
        @Column (nullable = false)
        @GeneratedValue (strategy = GenerationType.IDENTITY)
        @Extension (vendorName = "datanucleus", key = "gae.encoded-pk", value = "true")
        private String courseID;
    	
    	@Column (nullable = false)
    	private String courseName;
    	
    	@OneToMany (cascade=CascadeType.ALL)
    	private List<Standard> standards;
    	
    	public Course()
    	{
    		standards = new ArrayList<Standard>();
    	}
    	
    	public String getCourseID()
    	{
    		return courseID;
    	}
    	
    	public void setCourseID(String courseID)
    	{
    		this.courseID = courseID;
    	}
    	
    	public String getCourseName()
    	{
    		return courseName;
    	}
    	
    	public void setCourseName(String cn)
    	{
    		courseName = cn;
    	}
    	
    	public List<Standard> getStandards()
    	{
    		return standards;
    	}
    	
    	public void setStandards(List<Standard> stds)
    	{
    		standards = stds;
    	}	
    
        /**
         * Returns a string representation of the object. Resulting string contains
         * full name of the class and list of its properties and their values.
         *
         * @return <code>String</code> representation of this object.
         */
        @Override
        public String toString ()
        {
            return getClass().getName()
                   + "["
                   + "courseID=" + ((getCourseID() == null) ? "null" : getCourseID().toString())
                   + ", "
                   + "courseName=" + ((getCourseName() == null) ? "null" : getCourseName().toString())
                   + "]";
        }
    
    }
    standard_DataSource.ds.xml

    Code:
    <DataSource
        ID="standard_DataSource"
        serverConstructor="com.isomorphic.jpa.GAEJPADataSource"
        beanClassName="com.longfellow.egmockup.server.Standard"
        >
        <fields>
            <field name="standardID"    type="text" hidden="true"   primaryKey="true" />
            <field name="standardName"  type="text" title="Standard Name"    required="true"   />
            <field name="courseID" type="text" title="Course" canEdit="false"
                   foreignKey="course_DataSource.courseID"/>
        </fields>
    </DataSource>
    Standard.Java:

    Code:
    package com.longfellow.egmockup.server;
    
    import java.io.Serializable;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.ManyToOne;
    import org.datanucleus.jpa.annotations.Extension;
    
    @Entity
    public class Standard implements Serializable
    {
    	@Id
        @Column (nullable = false)
        @GeneratedValue (strategy = GenerationType.IDENTITY)
        @Extension (vendorName = "datanucleus", key = "gae.encoded-pk", value = "true")
        private String standardID;
    
        @Column (nullable = false)
        private String standardName;
    
        @Column (nullable = false)
        @Extension (vendorName = "datanucleus", key = "gae.parent-pk", value = "true")
        private String courseID;
    
        @ManyToOne (fetch=FetchType.LAZY)
        private Course course;
    
        public Standard ()
        {
        }
    
        public String getStandardID()
        {
            return standardID;
        }
    
        public void setStandardID (String standardID)
        {
            this.standardID = standardID;
        }
    
        public String getStandardName ()
        {
            return standardName;
        }
    
        public void setStandardName (String standardName)
        {
            this.standardName= standardName;
        }
    
        public String getCourseID()
        {
            return courseID;
        }
    
        public void setCourseID (String courseID)
        {
            this.courseID= courseID;
        }
    
        public Course  getCourse() {
            return course;
        }
    
        public void setCourse(Course course) {
            this.course = course;
        }
    
        /**
         * Returns a string representation of the object. Resulting string contains
         * full name of the class and list of its properties and their values.
         *
         * @return <code>String</code> representation of this object.
         */
        @Override
        public String toString ()
        {
            return getClass().getName()
                   + "["
                   + "standardID=" + ((getStandardID() == null) ? "null" : getStandardID().toString())
                   + ", "
                   + "cityName=" + ((getStandardName() == null) ? "null" : getStandardName().toString())
                   + "]";
        }
    }
    The exception:

    Code:
    java.lang.NullPointerException: null
        at com.smartgwt.client.widgets.grid.ListGrid.setDataSource(ListGrid.java:11390)
        at com.longfellow.egmockup.client.EmpoweringGradesMockup.onModuleLoad(EmpoweringGradesMockup.java:48)
    ...

    #2
    See the FAQ (sticky thread in this forum) for a list of common problems.

    Comment


      #3
      Thanks for the response - sorry I didn't see that FAQ entry. I went through the checklist and made sure every step was done. I hadn't been including the datasourceloader js file from the bootstrap.html file, so doing that got me farther.

      Now, running the same code as in the original post (but with the correct JS file included), my datasources seem to be loading into a component (ListGrid). The appropriate columns appear automatically, etc. Great!

      But:

      No changes to the data can be saved because of a server-side error:

      Code:
      === 2010-08-28 20:42:13,000 [1-11] WARN  RequestContext - dsRequest.execute() failed: 
      java.lang.NullPointerException
      	at com.isomorphic.jpa.EMF.returnEntityManager(EMF.java:95)
      	at com.isomorphic.jpa.GAEJPADataSource.executeAdd(GAEJPADataSource.java:382)
      	at com.isomorphic.datasource.DataSource.execute(DataSource.java:784)
      	at com.isomorphic.jpa.JPADataSource.execute(JPADataSource.java:94)
      	at com.isomorphic.application.AppBase.executeDefaultDSOperation(AppBase.java:721)
      	at com.isomorphic.application.AppBase.executeAppOperation(AppBase.java:658)
      	at com.isomorphic.application.AppBase.execute(AppBase.java:491)
      	at com.isomorphic.datasource.DSRequest.execute(DSRequest.java:1382)
      	at com.isomorphic.servlet.IDACall.handleDSRequest(IDACall.java:155)
      	at com.isomorphic.servlet.IDACall.processRequest(IDACall.java:106)
      	at com.isomorphic.servlet.IDACall.doPost(IDACall.java:54)
      	at javax.servlet.http.HttpServlet.service(HttpServlet.java:713)
      	at com.isomorphic.servlet.BaseServlet.service(BaseServlet.java:152)
      	at javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
      	at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
      The client side realizes this error with the following in the developer console:

      Code:
      15:42:13.153:XRP0:WARN:RPCManager:Error performing operation: 'custom': error: FAILURE, response: {operationId: "custom",
      clientContext: Obj,
      context: Obj,
      transactionNum: 0,
      httpResponseCode: 200,
      httpResponseText: "//isc_RPCResponseStart-->[{isDSResponse:..."[108],
      xmlHttpRequest: [object XMLHttpRequest],
      transport: "xmlHttpRequest",
      status: -1,
      clientOnly: undef,
      httpHeaders: Obj,
      isStructured: true,
      callbackArgs: null,
      results: Obj,
      isDSResponse: true,
      invalidateCache: false,
      data: null,
      startRow: 0,
      endRow: 0,
      totalRows: 0}
      These messages appear when I attempt to save a new entry to the DS. I am running in gae devmode, gae 1.3.6.

      I don't know where to go from here. Do I need to create a custom EMF for the GAEJPADataSource? I don't see that in the ds-gae example. Thanks for any hints - this forum has been really helpful so far, and that makes me feel safer about buying a pro license too. Sorry to keep pestering for incremental help!

      Comment


        #4
        Hi,

        Please check your server.properties file - for GAE there should be these properties defined:
        Code:
        # Default EMF provider implementation (implements EMFProviderInterface).
        # Fully qualified class name.
        # Existing implementations:
        # com.isomorphic.jpa.EMFProviderLMT - for Locally Managed Transactions (LMT)
        # com.isomorphic.jpa.EMFProviderNoTransactions - no transactions support
        # com.isomorphic.jpa.EMFProviderCMT - for Container Managed Transactions (CMT)
        jpa.emfProvider: com.isomorphic.jpa.EMFProviderLMT
        
        # Settings for LMT type
        
        # Name of the datasource
        jpa.persistenceUnitName: <UNIT_NAME_FROM_PERSISTENCE_XML>
        Check your logs for message: "Failed to initialize EMF provider".

        Or post here server.properties and persistence.xml files.

        Regards,
        Alius

        Comment


          #5
          Hi all.
          I have a same problem.
          I use smart client 2.3
          But I read FAQ and I have correct config files and other, I think.
          Here's my script tag from bootstrap.html file.
          Code:
          <script type="text/javascript" language="javascript" src="tboxmonitor/tboxmonitor.nocache.js"></script>
              <!--load the datasources-->
          	<script src="sc/DataSourceLoader?dataSource=aboutTerminalsAllDS,ds></script>
          Here's my server.properties file
          Code:
          webRoot: __AUTODETECT__  
          gwtModuleName: tboxmonitor
          isomorphicPathRootRelative: /tboxmonitor/sc  
          project.datasources: $webRoot/ds  
          project.ui: $webRoot/shared/ui  
          project.apps: $webRoot/shared/app
          here's my ds.ds.xml file, I take that from example and java file I take also, that's should exclude errors.
          Code:
          <DataSource  
              ID="ds"  
              serverConstructor="ru.webapp.tboxmonitor.server.UserDataSource"  
          >  
              <fields>  
                  <field name="userName"        type="text"           length="128"      required="true"/>  
                  <field name="employeeId"      type="sequence"       primaryKey="true" hidden="true"/>  
                  <field name="job"             title="Job Title"     type="text"       length="128"/>   
                  <field name="email"           title="Email"         type="text"       length="128"/>  
                  <field name="employeeType"    title="Employee Type" type="text"       length="40"/>  
                  <field name="salary"          title="Salary"        type="float"/>  
              </fields>  
                
          </DataSource>
          UserDataSource.java
          Code:
           * Isomorphic SmartGWT web presentation layer 
           * Copyright 2000 and beyond Isomorphic Software, Inc. 
           * 
           * OWNERSHIP NOTICE 
           * Isomorphic Software owns and reserves all rights not expressly granted in this source code, 
           * including all intellectual property rights to the structure, sequence, and format of this code 
           * and to all designs, interfaces, algorithms, schema, protocols, and inventions expressed herein. 
           * 
           *  If you have any questions, please email <sourcecode@isomorphic.com>. 
           * 
           *  This entire comment must accompany any portion of Isomorphic Software source code that is 
           *  copied or moved from this file. 
           */  
            
          package ru.webapp.tboxmonitor.server;
            
          //----------------------------------------------------------------------  
          // Custom DataSource example  
          //  
          // This class shows how to easily implement a completely customized  
          // DataSource that simply plugs into the SmartGWT Server framework  
          //----------------------------------------------------------------------  
            
          import java.util.ArrayList;  
          import java.util.HashMap;  
          import java.util.Iterator;  
          import java.util.List;  
          import java.util.Map;  
            
          import com.isomorphic.datasource.BasicDataSource;  
          import com.isomorphic.datasource.DSRequest;  
          import com.isomorphic.datasource.DSResponse;  
          import com.isomorphic.util.DataTools;  
            
          public class UserDataSource extends BasicDataSource {  
            
              private static List data = new ArrayList();  
              private static int nextId;  
            
              // Hard-coded data store  
              static {  
                  String[] userName = { "Charles Madigen", "Ralph Brogan", "Grigori Ognev", "Tamara Kane",  
                                        "Betsy Rosenbaum", "Gene Porter", "Prya Sambhus", "Ren Xian" };  
                  String[] jobTitle = { "Chief Operating Officer", "Manager Systems", "Technician",  
                                        "Manager Site Services", "Secretary", "Manager Purchasing",  
                                        "Line Worker", "Mobile Equipment Operator" };  
                  String[] email    = { "charles.madigen", "ralph.brogan", "grigori.ognev", "tamara.kane",  
                                        "elizabeth.rosenbaum", "gene.porter", "prya.sambhus", "ren.xian" };  
                  String[] type     = { "full time", "contract", "part time", "full time", "part time",  
                                        "contract", "part time", "full time" };  
                  float[] salary      = { 20395, 18076, 12202, 21227, 11632, 17702, 12985, 16402 };  
            
                  for (int i = 0; i < userName.length; i++) {  
                      Map map = new HashMap();  
                      map.put("employeeId", new Integer(i + 1));  
                      map.put("userName", userName[i]);  
                      map.put("job", jobTitle[i]);  
                      map.put("email", email[i] + "@server.com");  
                      map.put("employeeType", type[i]);  
                      map.put("salary", new Float(salary[i]));  
            
                      data.add(map);  
                  }  
                  nextId = data.size() + 1;  
              }  
            
              // Override all four CRUD operations - create, retrieve, update and delete  
              // (add, fetch, update and remove in SmartClient terminology).  
            
              // Note that the parameters sent by the client arrive here already converted to Java Maps  
              // by the SmartClient Server - with SmartClient Pro and Enterprise, there's no need to worry  
              // about conversion to and from XML or JSON even in a custom DS implementation  
            
              public DSResponse executeAdd(DSRequest req) throws Exception {  
                  Map map = req.getValues();  
                  map.put("employeeId", new Integer(nextId++));  
                  data.add(map);  
                  DSResponse resp = new DSResponse();  
                  resp.setData(req.getValues());  
                  resp.setStatus(0);  
                  return resp;  
              }  
            
              // There isn't enough data in this hard-coded example to make it worthwhile implementing  
              // paging; however, we could easily do so by using req.getStartRow() and req.getEndRow() to  
              // return just those records of the complete filtered list.  
              public DSResponse executeFetch(DSRequest req) throws Exception {  
                  List filteredData = null;  
                  if (req.getCriteria() != null) {  
                      String partialName = (String)req.getCriteria().get("userName");  
                      if (partialName != null) {  
                          filteredData = new ArrayList();  
                          for (Iterator i = data.iterator(); i.hasNext(); ) {  
                              Map map = (Map)i.next();  
                              String userName = (String)map.get("userName");  
                              if (userName != null && userName.contains(partialName)) {  
                                  filteredData.add(map);  
                              }  
                          }  
                      }  
                  }  
                  DSResponse resp = new DSResponse();  
                  resp.setData(filteredData == null ? data : filteredData);  
                  resp.setStatus(0);  
                  return resp;  
              }  
            
              public DSResponse executeRemove(DSRequest req) throws Exception {  
                  Long work = (Long)req.getValues().get("employeeId");  
                  if (work != null) {  
                      Integer key = new Integer(work.intValue());  
                      for (Iterator i = data.iterator(); i.hasNext(); ) {  
                          Map map = (Map)i.next();  
                          if (key.equals(map.get("employeeId"))) {  
                              i.remove();  
                              break;  
                          }  
                      }  
                  }  
                  DSResponse resp = new DSResponse();  
                  resp.setData(req.getOldValues());  
                  resp.setStatus(0);  
                  return resp;  
              }  
              public DSResponse executeUpdate(DSRequest req) throws Exception {  
                  Map map = req.getOldValues();  
                  Long work = (Long)req.getValues().get("employeeId");  
                  if (work != null) {  
                      Integer key = new Integer(work.intValue());  
                      for (int i = 0; i < data.size(); i++) {  
                          map = (Map)data.get(i);  
                          if (key.equals(map.get("employeeId"))) {  
                              DataTools.mapMerge(req.getOldValues(), map);  
                              DataTools.mapMerge(req.getValues(), map);  
                              break;  
                          }  
                      }  
                  }  
                  DSResponse resp = new DSResponse();  
                  resp.setData(map);  
                  resp.setStatus(0);  
                  return resp;  
              }  
          }
          and here's my *.gwt.xml

          Code:
          <?xml version="1.0" encoding="UTF-8"?>
          <module rename-to='tboxmonitor'>
          
              <inherits name="com.smartgwtee.SmartGwtEE"/>
              <inherits name="com.smartgwtee.tools.Tools"/>
              
              <entry-point class='ru.webapp.tboxmonitor.client.Tboxmonitor'/>
          
            <source path='client'/>
            <source path='shared'/>
            
            <extend-property name="locale" values="ru_RU"/>
          
          </module>
          When I use
          Code:
          DataSource.load("ds", null, true);
          UserDataSource.java reflect and server say
          Code:
          DEBUG XML - Parsed XML from D:\EclipseHeliosWorkspaces\new_tboxmonitor\tboxmonitor\war\ds\ds.ds.xml: 10ms
          but DataSource.get("ds") still does not work.

          Comment


            #6
            You don't need to use DataSource.load() if you've got a reference to the DataSourceLoader servlet in your host .html file.

            However you don't seem to have hit all the points in the FAQ (Firebug Net panel, checking whether DataSourceLoader is in web.xml etc).

            Comment


              #7
              thanks for your response Isomorphic.
              It works the problem was that the script for DataSourseLoader placed before
              script __gwt_historyframe.

              And I getting next problem :( how i can cast
              com.smartgwt.client.data.DataSourceand
              and MyDataSource with override transform request response methods.
              is that's code
              Code:
              MyDataSource ds = (MyDataSource)com.smartgwt.client.data.DataSourceand.get("dsID");
              cause of the error.

              Comment


                #8
                Generally with a server-based DataSource, use DMI rather than transformRequest/Response. See the QuickStart Guide, Server Framework chapter, for an overview of using DMI.

                Comment

                Working...
                X