tags:

views:

505

answers:

3

Hi all.

Still wresting with GWT and App Engine, and I have come to this problem:

I have an app engine populated with various data, which I would like to present on the client using a GWT RPC.

I have found out the hard way that, because my Model objects are annotated with JDO, i can't just send them back to the client because they aren't serializable. This means I'm going to have to create a layer of intermediate classes to extract data from my model objects, and send it back to the client to use asynchronously.

I am wondering though, it is possible to construct a GWT object in a servlet and send it back to be used? For example, the servlet would be receive my asynchronous request, pull out the data i want from the database, create a GWT VerticalPanel() with appropriate child elements for the data, and send that VerticalPanel back to the client to be injected.

My understanding of the Java / Javascript interaction that is going on here is still foggy, and I'm thinking that sending a Java object that is not compiled to Javascript after the application is deplyed will not work. Can anybody clarify this for me?

A: 

This is (imho) one of the problems with GWT.

Basically in Java Web applications it's pretty common to have data or domain objects (which would be your JDO objects) and presentation objects, which are sent to the view. Some go much further than this and can have many more layers of abstraction ("go ahead, add one more layer").

I can see the argument for this but it adds a lot of boilerplate as you translate objects between layers.

Anyway, in GWT you need to do this if your domain objects are POJOs (and as with JPA, even though they claim to be POJOs, the annotations make them not so in reality).

GWT will do this for you on objects returned by your RPC interface but there are certain classes you can't use (eg BigDecimal) as there is no Javascript equivalent (so to use BigDecimals you pass Strings around to construct BigDecimals yourself on the serverside when you ened them and convert them back to Strings when you send them to the client).

cletus
+4  A: 

No the server can't create GWT UI objects (like vertical panels) to be used in the presentation layer, nor should it, that's why it's called a 'server' and a 'presentation layer' one serves the data and handles all the business logic, the other displays things on a screen and allows a user to interact with them.

You can however send your JPA annotated POJO's to the front end just fine (we do it in all our applications). You simply need to include the source code for the annotations themselves so that GWT knows how to compile them. You also need to make sure your POJOs's are in a package that is referenced by a NameOfXmlFile.gwt.xml file, eg:

<module>
    <inherits name='com.google.gwt.user.User'/>
    <source path="domain" />
</module>

This file in my case is in a folder above a package called 'domain' where all my JPA annotated POJO's live. Then in your client side you tell it to inherit that .gwt.xml file:

<module>
        <inherits name='com.google.gwt.user.User'/>
        <!-- Domain layer references -->
        <inherits name='your.package.structure.NameOfXmlFile'/>
</module>

There are restrictions on what you can put in those classes (like for example BigDecimal is not supported, etc) but anything that can be compiled by the GWT compiler (and JPA annotations certainly can be) can be sent without needing any kind of transfer objects. This is one of the real strengths of GWT, that you can use the same JPA Pojos in your entire application, without ever needing to create any other similar object.

Edit: I just noticed you said JDO and not JPA. I assume the same applies there as well though if they are just annotations?

rustyshelf
Thanks for your help. I think this is pretty much the approach I want to take. the problem I am forseeing is how to use POJO's to transfer the App Engine datatypes. Say for example I wanted to store Contact objects in the datastore and pass them back to the client as POJOs. fields like firstName and lastName would be simple because those are generally just strings, but what about a photo of the contact? That would probably need to go into the db as a Blob which I would not have the sourcecode for on the client.
darren
The general approach we take to images is to store their file URLs on the back end and store the actual images on the filesystem, then when we send those POJO's to the client we convert the file URLs to http URLs that the client can display.Another approach is to keep them in the database as a BLOB and provide a servlet that streams the BLOB back to the client as an image, and store the URL to the servlet for that BLOB in your POJO.
rustyshelf
It isn't so much the annotations that are problematic for GWT to serialize, it is the "hidden" fields that JDO adds during the bytecode enhancement process. A JDO pojo isn't necessarily "just" a pojo, it can have metadata too.
Peter Recore
Bytecode enhancements are irrelevant to GWT, it compiles from the source code, not the byte code. This may still cause you problems at run-time though if JDO depends on those hidden properties. Sounds like JPA is the cleaner way to go then?
rustyshelf
A fairly simple way to handle sending objects from the server, that have been retrieved from the database, to the client is to use Dozer (http://dozer.sourceforge.net/) to copy your objects, essentially removing all of the extra stuff JDO adds. It's really simple if you are just copying objects. It's recursive and can be done server side.
Nick
A: 

I've seen good answers, so I won't repeat myself..

Anyway my simple but vital suggestion is: the only way to go is through POJO objects.. BUT IMHO to avoid fucking problems, remember that your POJO objects SHOULD be really PLAIN

Anyway, I can suggest you also a little framework I recently did (few hours of work, so don't expect a rocket!).

It is pojo-injector: http://code.google.com/p/pojo-injector

It helps you in translating your data models to POJO and back... It's based on annotations (only on the POJO side!)...

I hope it can help..

Best regards,

CA

Carlo Alberto Degli Atti