I try to store a Google User (com.google.appengine.api.users.User) inside of an own class in google datastore using objectify. I am using objectify (com.googlecode.objectify) version 5.0.3 and (com.sappenin.objectify) version 5.0.2. This is my class:
@Entity
public class UserTest {
@Id
public Long id;
@Index
public User user;
public UserTest() {}
public UserTest(User user) {
super();
this.user = user;
}
}
Now I try to store an object of this class using the following servlet class:
import static OfyService.ofy;
@Path("/userStore")
public class UserStoreTestService {
@POST
@Produces(MediaType.APPLICATION_JSON)
public User saveUser() {
Key<UserTest> key = ofy().save().entity(new UserTest(getUser())).now();
UserTest userTest = ofy().load().key(key).now();
return userTest.user;
}
@GET
@Produces(MediaType.APPLICATION_JSON)
public User loadUser() {
UserTest userTest = ofy().load().type(UserTest.class)
.filter("user", getUser()).first().now();
return userTest.user;
}
private User getUser() {
return UserServiceFactory.getUserService().getCurrentUser();
}
}
My ofy service looks like that:
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyFactory;
import com.googlecode.objectify.ObjectifyService;
public class OfyService {
static {
factory().register(UserTest.class);
}
public static Objectify ofy() {
return ObjectifyService.ofy();
}
}
When I do a POST request i get this JSON code:
{"email":"test@example.com","authDomain":"gmail.com","userId":"18580476422013912411","federatedIdentity":null,"nickname":"test@example.com"}
When I do a GET request after the POST I get this JSON code:
{"email":"test@example.com","authDomain":"gmail.com","userId":"-1405876145","federatedIdentity":null,"nickname":"test@example.com"}
The first Id is 18580476422013912411 the second one is -1405876145 .
What am I doing wrong?
According to this question , App Engine's datastore can store numbers up to 9,223,372,036,854,775,807
(unsigned long limit). The userId
is bigger, hence your issue.
You should store your userId
in a String. Anyway, you will not perform any numeric operation on it I assume (comparison, addition, division...).
Here a quick workaround would be to store the userId
as String in your custom UserTest
class, and accept that the userId
in the user
attribute will be wrong.
Another option would be to use the @Serialize
annotation to store your User
object in serialized mode. That way the long will remain untouched.
But more generally, you should not try to store classes that you do not control, because you will end up with issues like this. Here you're unable to convert the userId
to a String
, but you will also have issues if Google decides to updates its User
class later.
Instead you should rather create your own MyUser
class and manipulate it. Of course the downside is that you'll have to copy data from the original object to your custom one.
This looks like some sort of issue in GAE's User object. I would create an example that uses the low-level API and submit it to Google as a bug. It's interesting (and probably relevant) that the value is larger than an unsigned 64 bit integer, but since the value is a String, this is theoretically legal. What's going on under the covers is anyone's guess (outside of Google, that is).
Objectify is not involved; it just passes User objects as-is to the low level API.
If you look at the sources of User
, you'll see that userId
is not used in User
object identity, ie equals()
or hash()
do not depend on it. The user identifier seems to be determined by auth domain and email.
So, do not worry about userId
, use User.equals()
to check for user identity.
I'm not sure how querying on field of type User
is performed by GAE datastore, but I'd expect google to handle this properly (= the same as object identity). Anyhow you can test this easily with a quick query. If it does not perform as expected, then you can create your own user identity field in a similar way that .equals()
does: contatenate auth domain and email together to create a user identity string.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.