I am using appengine cloud endpoints and objectify. I have previously deployed these endpoints before and now I am updating them and it is not working with Objectify. I have m
Others already mentioned how to approach this with @ApiResourceProperty
and @ApiTransformer
. But I do need the key available in client-side, and I don't wanna transform the whole entity for every one. I tried replacing the Objectify Key with com.google.appengine.api.datastore.Key
, and it looks like it worked just fine as well in my case, since the problem here is mainly due to that endpoint does not support parameterized types.
Because of the popularity of Objectify, a workaround was added in prior releases to support the Key
type, until a more general solution was available. Because the new solution is available, the workaround has been removed. There are two ways you can now approach the issue with the property.
I came up with the following solution for my project:
@Entity
public class Car {
@Id Long id;
@ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
Key<Driver> driver;
public Key<Driver> getDriver() {
return driver;
}
public void setDriver(Key<Driver> driver) {
this.driver = driver;
}
public Long getDriverId() {
return driver == null ? null : driver.getId();
}
public void setDriverId(Long driverId) {
driver = Key.create(Driver.class, driverId);
}
}
@Entity
public class Driver {
@Id Long id;
}
I know, it's a little bit boilerplate, but hey - it works and adds some handy shortcut methods.
At first, I did not understand the answer given by Flori, and how useful it really is. Because others may benefit, I will give a short explanation.
As explained earlier, you can use @ApiTransformer
to define a transformer for your class. This would transform an unserializable field, like those of type Key<myClass>
into something else, like a Long
.
It turns out that when a class is processed by GCE, methods called get{fieldName}
and set{FieldName}
are automatically used to transform the field {fieldName}
. I have not been able to find this anywhere in Google's documentation.
Here is how I use it for the Key{Machine}
property in my Exercise
class:
public class Exercise {
@ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
public Key<Machine> machine;
// ... more properties
public Long getMachineId() {
return this.machine.getId();
}
public void setMachineId(Long machineId) {
this.machine = new Key<Machine>(Machine.class, machineId);
}
// ...
}