GWT with JDO issue

I am just starting to play with GWT. It is very difficult for me to make GWT + JAVA + JDO + Google AppEngine while working with DataStore. I tried to follow a different tutorial, but no luck. For example, I go to these tutorials: TUT1 TUT2

I was not able to figure out how and what I need to do to make this work. Please look at my simple code and tell me what I need to do so that I can save it to the data store:

1. ADDRESS ENTITY

package com.example.rpccalls.client; import java.io.Serializable; import javax.jdo.annotations.IdGeneratorStrategy; import javax.jdo.annotations.Persistent; import javax.jdo.annotations.PrimaryKey; public class Address implements Serializable{ @PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) private int addressID; @Persistent private String address1; @Persistent private String address2; @Persistent private String city; @Persistent private String state; @Persistent private String zip; public Address(){} public Address(String a1, String a2, String city, String state, String zip){ this.address1 = a1; this.address2 = a2; this.city = city; this.state = state; this.zip = zip; } /* Setters and Getters */ } 

2. HUMAN PERSONS

 package com.example.rpccalls.client; import java.io.Serializable; import java.util.ArrayList; import javax.jdo.annotations.IdGeneratorStrategy; import javax.jdo.annotations.PersistenceCapable; import javax.jdo.annotations.Persistent; import javax.jdo.annotations.PrimaryKey; import com.google.appengine.api.datastore.Key; @PersistenceCapable public class Person implements Serializable{ @PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) private Key key; @Persistent private String name; @Persistent private int age; @Persistent private char gender; @Persistent ArrayList<Address> addresses; public Person(){} public Person(String name, int age, char gender){ this.name = name; this.age = age; this.gender = gender; } /* Getters and Setters */ } 

3. RPCCalls

 package com.example.rpccalls.client; import java.util.ArrayList; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.TextBox; public class RPCCalls implements EntryPoint { private static final String SERVER_ERROR = "An error occurred while attempting to contact the server. Please check your network connection and try again."; private final RPCCallsServiceAsync rpccallService = GWT.create(RPCCallsService.class); TextBox nameTxt = new TextBox(); Button btnSave = getBtnSave(); public void onModuleLoad() { RootPanel.get("inputName").add(nameTxt); RootPanel.get("btnSave").add(btnSave); } private Button getBtnSave(){ Button btnSave = new Button("SAVE"); btnSave.addClickHandler( new ClickHandler(){ public void onClick(ClickEvent event){ saveData2DB(nameTxt.getText()); } } ); return btnSave; } void saveData2DB(String name){ AsyncCallback<String> callback = new AsyncCallback<String>() { public void onFailure(Throwable caught) { Window.alert("WOOOHOOO, ERROR: " + SERVER_ERROR); // TODO: Do something with errors. } public void onSuccess(String result) { Window.alert("Server is saying: ' " + result + "'"); } }; ArrayList<Address> aa = new ArrayList<Address>(); aa.add(new Address("123 sasdf","", "Some City", "AZ", "93923-2321")); aa.add(new Address("23432 asdf", "Appt 34", "Another City", "AZ", "43434-4432")); Person p = new Person(); p.setName(name); p.setAge(23); p.setGender('m'); p.setAddresses(aa); // !!!!!!!!!!!!!!!!!! SERVER CALL !!!!!!!!!!!!!!!!!! rpccallService.saveName(p, callback); // !!!!!!!!!!!!!!!!!! SERVER CALL !!!!!!!!!!!!!!!!!! } } 

4. RPCCallsService

 package com.example.rpccalls.client; import com.google.gwt.user.client.rpc.RemoteService; import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; @RemoteServiceRelativePath("calls") public interface RPCCallsService extends RemoteService { String saveName(Person p); } 

5. RPCCallsServiceAsync

 package com.example.rpccalls.client; import com.google.gwt.user.client.rpc.AsyncCallback; public interface RPCCallsServiceAsync { void saveName(Person p, AsyncCallback<String> callback); } 

6. ** RPCCalls.gwt.xml

 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.6.4//EN" "http://google-web-toolkit.googlecode.com/svn/tags/1.6.4/distro-source/core/src/gwt-module.dtd"> <module rename-to='rpccalls'> <inherits name='com.google.gwt.user.User'/> <inherits name='com.google.gwt.user.theme.standard.Standard'/> <entry-point class='com.example.rpccalls.client.RPCCalls'/> </module> 

I tried to add the Key class and everything else in these tutorials, but it looks like I'm missing something.

Here is my mistake: alt text http://vasura.s3.amazonaws.com/Picture2.png

or before I got this error:

The key cannot be allowed for type

What is the best solution for this job?

+6
java google-app-engine rpc gwt google-cloud-datastore
source share
6 answers

Sriram Narayan says String-encode Key to get it to go through the GWT RPC mechanism:

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class SomeDomainClass implements Serializable {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
@Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value = "true")
String id;

+8
source share

The second tutorial that you referenced has a section on how to obscure the com.google.appengine.api.datastore.Key class, since it is not available for GWT:

Since I am not doing anything with the Key class on the client, I am going to exclude it. This actually takes a few steps and includes the super-src function of the GWT XML module files.

You might want to take a look at the GWT documentation , which says that

The heart of GWT is a compiler that converts a Java source to JavaScript

therefore, you need to have source code to use this class in client code.

+3
source share

Once you're tired of JDO, look at objectify . I found that working with it is much nicer, and it has a full GWT interface without DTO.

+3
source share

You can use the Key class in GWT code by adding these additional jar files:

http://www.resmarksystems.com/code/

  • AppEngine-Utils-Client-1.0.jar
  • AppEngine-Utils Server 1.0.jar

This basically gives the GWT compiler a GWT-compatible version of Key and other AppEngine classes. (e.g. Text, Blob, and User).

For use:

  • Add appengine-utils-client-1.0.jar anywhere in the build path.
  • Place the file appengine-utils-server-1.0.jar in the WEB-INF / lib folder.
  • Add the following to your GWT module:
    • <inherits name = "com.resmarksystems.AppEngineDataTypes" / ">
+3
source share

Another option is to implement the DTO (data transfer object) that you use in the client, instead of directly using persistent objects. Or you can go to JPA instead of JDO. In the data class example in JPA applications, the JPA application Id is long instead of this key implementation http://code.google.com/appengine/docs/java/datastore/usingjpa.html

+1
source share

Maybe you forgot to create an implementation for RPCCallsService? I do not see it from the list of files that you have.

You must have the RPCCallsServiceImpl.java file in RPCCalls / src / com / example / rpccalls / server /, this is the implementation file for the RPCCallsService.java interface.

It will look something like this:

 import javax.jdo.JDOHelper; import javax.jdo.PersistenceManager; import javax.jdo.PersistenceManagerFactory; import com.google.gwt.user.server.rpc.RemoteServiceServlet; import com.example.rpccalls.client.RPCCallsService; public class RPCCallsServiceImpl extends RemoteServiceServlet implements RPCCallsService { // Factory to get persistence manager object later private static final PersistenceManagerFactory PMF = JDOHelper.getPersistenceManagerFactory("transactional-optional"); public String saveName(Person p) { // Data Store need persistence manager object for writing to it PersistenceManager pm = PMF.getPersistenceManager(); // Recommended way to save an object to the data store try { pm.makePersistent(p); } finally { pm.close(); } // You want it to return string return p.getName(); } } 

Hope this helps you solve the problem. Greetings :)

+1
source share

All Articles