RequestFactory & JPA: Does the table has to has a field called Version?

336 views
Skip to first unread message

Mike.G

unread,
Jan 12, 2011, 9:49:40 AM1/12/11
to google-we...@googlegroups.com
hi All:

From the GWT doc it says:

one of 4 special methods are required on all entities as they are used by the RequestFactory servlet is:

Integer getVersion()


but i am working on a system that already has a DB schema(MySql), i'd like to use RF to do CRUD operations, so do i have to insert each table a version column? is there other way i can use RF without had each table a "version" column?

thanks very much.

Mike.G

unread,
Jan 12, 2011, 9:56:10 AM1/12/11
to google-we...@googlegroups.com
i try to add @Transient to the version field in Entity, however it return exception:
SEVERE: Unexpected error
com.google.gwt.requestfactory.server.UnexpectedException: The persisted entity with id 2110 has a null version
at com.google.gwt.requestfactory.server.SimpleRequestProcessor.createReturnOperations(SimpleRequestProcessor.java:283)
at com.google.gwt.requestfactory.server.SimpleRequestProcessor.process(SimpleRequestProcessor.java:226)
at com.google.gwt.requestfactory.server.SimpleRequestProcessor.process(SimpleRequestProcessor.java:125)
at com.google.gwt.requestfactory.server.RequestFactoryServlet.doPost(RequestFactoryServlet.java:118)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
...

Jan Swaelens

unread,
Jan 12, 2011, 9:59:11 AM1/12/11
to google-we...@googlegroups.com
You do not need to do that, the RequestFactory comes with a concept of 'Locator's which help you to overcome this issue.
Have a look here for the Locator documentation: link
And have a search in the archives of this group, you can find some examples that should help you along.

Mike.G

unread,
Jan 12, 2011, 10:29:40 AM1/12/11
to google-we...@googlegroups.com
thanks very very much for your reply, i even didn't know that before. i'll see that right now.

Jan Swaelens

unread,
Jan 12, 2011, 10:45:16 AM1/12/11
to google-we...@googlegroups.com
This is an extract from a post that helped me a lot:

If you can implement a single Locator class that works for all your
entities, then go with it; and otherwise make one for each entity.
For instance, if you have a base class for your entities that provides an ID
and version, then you can easily cast any entity to that class to implement
getId and getVersion, and you probably can implement getIdType by returning
a fixed type.
You can clazz.newInstance() in the create() or use
PersistenceManager#newInstace with JDO.
And you can easily "find" using the Class and ID with JPA using
EntityManager#find(clazz,id), or with JDO using
PersistenceManager#getObjectById(clazz,id).
 
Basically, you could very well have only one Locator class per "id type".
 
Oh, and something to keep in mind: the Locator and *your services* instances
(not the ServiceLocator instances though) are cached aggressively and reused
for all subsequent requests, so make sure they are thread-safe !
(have a look at the ServiceLayerCache class to see all "memoized" methods)

David Chandler

unread,
Jan 12, 2011, 11:19:33 AM1/12/11
to google-we...@googlegroups.com
Here's a quick project I threw together to illustrate the use of Locator and ServiceLocator with Objectify:


Thanks very much to Thomas and Didier, whose posts on various forums instigated this exercise.

The cool thing about 2.1.1 is that you can use a generic DAO to handle all the common operations (find, put, delete, etc.) as shown in the sample project. With a generic DAO service, locator, and service locator, all you need per entity is

1) Entity DAO that extends your base DAO. It may be empty if it uses only the standard DAO methods.
2) EntityProxy interface
3) RequestFactory service stub that defines the methods actually called on the client. There is an open issue (http://code.google.com/p/google-web-toolkit/issues/detail?id=5807) to allow these interfaces to inherit from a base interface, which would eliminate repetition of methods in the generic DAO service.

/dmc

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.



--
David Chandler
Developer Programs Engineer, Google Web Toolkit
w: http://code.google.com/
b: http://googlewebtoolkit.blogspot.com/
t: @googledevtools

Johannes Tuchscherer

unread,
Jan 26, 2011, 2:02:11 AM1/26/11
to google-we...@googlegroups.com
David, thanks a lot for this sample project. You answered about 10 of mine questions about the RequestFactory and Objectify by posting this link.

Ido

unread,
Feb 9, 2011, 1:18:51 PM2/9/11
to google-we...@googlegroups.com
Hi,

Sorry for inturrupting this thread, I'm a new to web development and a very junior GWT one, so sorry in advanced for every mistake.

I'm implementing these days a GWT application from scratch, the data scope is assembled with Hibernate,Oracle and baking it with the RequestFactory mechanism, using the DynaTableRf, Expenses and listwidget projects as reference for my work.

All three projects use 'Version' as field in their database. I wouldn't mind adding this version field unless I was inherited the project's data structures (pojos etc...).
I read carefully the updated version of Getting Started With RequestFactory and many other threads like this, but couln't understand how can I use properly the request factory without having this version field.

The document mentioned that my extended Locator should/can contain the method: Object getVersion(T domainObject), however, by the samples projects and by method's signature, the implementation should be something like:
public Object getVersion(DatastoreObject domainObject)
{
return domainObject.getVersion();
}

the problem is that I cannot see anyway how my domainObject contains version number (without having this field in the database). was trying @Transient and base class as in listwidget project but with no help.

Will be very happy for any answer or example of how using the Locator for bypass implementation of getVersion in the Entity it self.


 Thanks in advanced,
Ido



Thomas Broyer

unread,
Feb 9, 2011, 1:58:16 PM2/9/11
to google-we...@googlegroups.com
The version is only used to decide whether to fire EntityProxyChange events with WriteOperation==UPDATE, so if you don't need to use these events, you can simply always return the same value (but not 'null' !)

Ido

unread,
Feb 9, 2011, 2:30:42 PM2/9/11
to google-we...@googlegroups.com
Hi Thomas,

Thanks for the quick reply (and for your blog of course).
Seems like I  misunderstood the getVersion issue as I thought the locator could resolve it, Actually was mentioned in this thread, few posts above.

Since the listwidget project makes an extensive usage of the EntityProxyChanged events which I'll be sorry for not using it as well, I would just want a final clarification;
Using the EntityProxyChanged events requires me to add version field in the database as well as in the entity itself. 
Is that right?

And again, thanks a lot!
Ido

Thomas Broyer

unread,
Feb 9, 2011, 3:54:35 PM2/9/11
to google-we...@googlegroups.com
If you want to be able to know when an object has changed, you have to have a axis of comparison for this. In RequestFactory, this is the "version", which can be any kind of object (IIRC, its toString() will be used).
So either you have a "version" property in your database (could be auto-incremented at each save, or a timestamp) or you synthesize one yourself (e.g. based on the all the properties of the object; sort of "checksum" of the object).
If you cannot tell whether two objects (representing the same database row, but "taken" at different points in time) are the same, then you cannot have a notion of "update", and RequestFactory cannot possibly fire EntityProxyChange(UPDATE) events.
Message has been deleted

Youngster

unread,
Feb 21, 2011, 4:40:44 PM2/21/11
to google-we...@googlegroups.com
Hi David,

When I´m trying to use your objectifyDao from the list widget project, Eclipse warns me already for an unsafe type cast in this code:

                clazz = (Class<T>) ((ParameterizedType) getClass()
                                .getGenericSuperclass()).getActualTypeArguments()[0];

When trying to run my application I get the following error:

[ERROR] Unexpected error
java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
    at apps.youngster.mole.server.service.ObjectifyDao.<init>(ObjectifyDao.java:49)

Do you have any idea what can cause this? I can´t find any obvious difference with your code...

Thanks!
Reply all
Reply to author
Forward
0 new messages