I was trying to set-up a really trivial RequestFactory example, but I failed. I persist entities in to my datastore just find, however when trying to pull them out again, i get a
com.google.web.bindery.requestfactory.server.UnexpectedException: The persisted entity with id aglub19hcHBfaWRyCgsSBFVzZXIYBAw has a null version
So first of all this is my JPO annotated entity class. At the end you find to static function for RequestFactory to call, and a non-static member function which will become an InstanceRequest.
package com.test.server;
import java.util.List;
import javax.jdo.PersistenceManager;
import javax.jdo.annotations.Column;
import javax.jdo.annotations.Extension;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import javax.jdo.annotations.Version;
import javax.jdo.annotations.VersionStrategy;
@PersistenceCapable(identityType = IdentityType.APPLICATION)
@Version(strategy = VersionStrategy.VERSION_NUMBER, column = "VERSION", extensions = { @Extension(vendorName = "datanucleus", key = "field-name", value = "version") })
public class User {
public User() {
}
public User(String name) {
this.name = name;
}
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
@Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value = "true")
private String id;
@Persistent
@Column(name = "version")
private Integer version;
@Persistent
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Integer getVersion() {
return version;
}
public void setVersion(Integer version) {
this.version = version;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static final PersistenceManager persistenceManager() {
return PMF.get().getPersistenceManager();
}
@SuppressWarnings("unchecked")
public static List<User> findAllUsers() {
PersistenceManager pm = persistenceManager();
try {
String query = "SELECT FROM " + User.class.getName();
List<User> objects = (List<User>) pm.newQuery(query).execute();
objects.size(); // This is the workaround to retrieve all objects
return objects;
} finally {
pm.close();
}
}
public static User findUser(String id) {
PersistenceManager pm = persistenceManager();
try {
User u = pm.getObjectById(User.class, id);
return u;
} finally {
pm.close();
}
}
public void persist() {
PersistenceManager pm = persistenceManager();
try {
pm.makePersistent(this);
} finally {
pm.close();
}
}
}
The RequestFactory interface itself is really simple
package com.test.shared;
import com.google.web.bindery.requestfactory.shared.RequestFactory;
public interface UserOrderRequestFactory extends RequestFactory {
UserRequest userRequest();
}
so is the corresponding RequestContext
package com.test.shared;
import java.util.List;
import com.google.web.bindery.requestfactory.shared.InstanceRequest;
import com.google.web.bindery.requestfactory.shared.RequestContext;
import com.google.web.bindery.requestfactory.shared.Service;
import com.google.web.bindery.requestfactory.shared.Request;
import com.test.server.User;
@Service(User.class)
public interface UserRequest extends RequestContext {
Request<List<UserProxy>> findAllUsers();
InstanceRequest<UserProxy, Void> persist();
}
Here is the proxy of user for the client side
package com.test.shared;
import com.google.web.bindery.requestfactory.shared.EntityProxy;
import com.google.web.bindery.requestfactory.shared.EntityProxyId;
import com.google.web.bindery.requestfactory.shared.ProxyFor;
@ProxyFor(com.test.server.User.class)
public interface UserProxy extends EntityProxy {
EntityProxyId<UserProxy> stableId();
String getName();
void setName(String name);
}
and finally my onModuleLoad() which first persists a user and then gets a list of all users.
public void onModuleLoad() {
final EventBus eventBus = new SimpleEventBus();
requestFactory = GWT.create(UserOrderRequestFactory.class);
requestFactory.initialize(eventBus);
UserRequest userRequest = requestFactory.userRequest();
UserProxy user = userRequest.create(UserProxy.class);
user.setName("Luigi");
userRequest.persist().using(user).fire( new Receiver<Void>()
{
@Override
public void onSuccess(Void arg0)
{
GWT.log("User persisted.");
}
});
userRequest = requestFactory.userRequest();
Request<List<UserProxy>> findAllUsersRequest = userRequest.findAllUsers();
findAllUsersRequest.fire( new Receiver<List<UserProxy>>() {
@Override
public void onSuccess(List<UserProxy> list) {
for(UserProxy u: list) {
GWT.log(u.getName());
}
}
});
Any input is welcome. I would be happy to receive any advice on this.
Thank you in advance.
While JPA seems to do this automatically it seems to be my job to advance the version counter in JDO. I added the following code to my persist routine in User.java
// JPA @Version does this automatically, but JDO @Version is not working like that. Not sure why.
if (version == null) {
version = 0l;
}
version++;