google app engine - plugin - Objectify con Cloud Endpoints
objectify en español (4)
Al principio, no entendí la respuesta dada por Flori y lo útil que es en realidad. Debido a que otros pueden beneficiarse, daré una breve explicación.
Como se explicó anteriormente, puede usar @ApiTransformer
para definir un transformador para su clase. Esto transformaría un campo que no se puede serializar, como los de tipo Key<myClass>
en otra cosa, como un Long
.
Resulta que cuando GCE procesa una clase, los métodos llamados get{fieldName}
y set{FieldName}
se usan automáticamente para transformar el campo {fieldName}
. No he podido encontrar esto en ninguna parte en la documentación de Google.
Aquí es cómo lo uso para la propiedad Key{Machine}
en mi clase de Exercise
:
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);
}
// ...
}
Estoy utilizando los puntos finales de la nube de Appengine y objetivar. Anteriormente había implementado estos puntos finales y ahora los estoy actualizando y no está funcionando con Objectify. Me mudé a una máquina nueva y ejecuté la última versión 1.8.6. He intentado poner objectify en el classpath y eso no funcionó. Sé que esto puede funcionar, ¿qué me falta?
Cuando se ejecuta endpoints.sh:
Error: Parameterized type
com.googlecode.objectify.Key<MyClass> not supported.
ACTUALIZACIÓN: volví a mi computadora anterior y corrí endpoints.sh en el mismo punto final y funcionó bien. La máquina antigua tiene 1.8.3. Estoy utilizando objectify 3.1.
ACTUALIZACIÓN 2: Actualicé mi máquina anterior a 1.8.6 y obtengo el mismo error que otra máquina. Deja 2 posibilidades: 1) Los puntos finales ya no admiten objectify 3.1 o 2) Los puntos finales tienen un error en la versión más reciente
Probablemente el # 1 ... He querido actualizar a 4.0 de todos modos ...
Debido a la popularidad de Objectify, se agregó una solución alternativa en las versiones anteriores para admitir el tipo de Key
, hasta que haya una solución más general disponible. Debido a que la nueva solución está disponible, la solución ha sido eliminada. Hay dos formas en que puede abordar el problema con la propiedad.
- Agregue una anotación
@ApiResourceProperty
que hace que la clave se omita de su objeto durante la serialización. Utilice este enfoque si desea una solución simple y no necesita acceso a la clave de sus clientes. - Agregue una anotación
@ApiTransformer
que proporcione un mecanismo compatible para serializar / deserializar el campo. Utilice este enfoque si necesita acceso a la clave (o una representación de la misma) en sus clientes. Como esto requiere escribir una clase de transformador, es más trabajo que la primera opción.
Otros ya mencionaron cómo abordar esto con @ApiResourceProperty
y @ApiTransformer
. Pero necesito la clave disponible en el lado del cliente, y no quiero transformar la entidad completa para cada uno. Intenté reemplazar la Clave de Objectify con com.google.appengine.api.datastore.Key
, y parece que funcionó bien también en mi caso, ya que el problema aquí se debe principalmente a que el punto final no admite tipos parametrizados.
Se me ocurrió la siguiente solución para mi proyecto:
@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;
}
Lo sé, es un poco repetitivo, pero bueno, funciona y agrega algunos métodos prácticos de acceso directo.