我正在使用appengine云端点和客观化。我之前已经部署了这些端点,现在我正在更新它们,并且它不能与Objectify一起使用。我已经搬到了新机器并运行最新的appengine 1.8.6。尝试将objectify放在classpath中并且不起作用。我知道这可以工作,我错过了什么?
运行endpoints.sh时:
Error: Parameterized type
com.googlecode.objectify.Key<MyClass> not supported.
更新: 我回到旧计算机并在同一端点上运行endpoints.sh并且运行正常。旧机器有1.8.3。我正在使用objectify 3.1。
更新2: 将我的旧机器更新为1.8.6并获得与其他机器相同的错误。留下2种可能性: 1)终点不再支持客观化3.1 或 2)端点在最新版本中存在错误
最有可能是#1 ......无论如何我一直想要更新到4.0 ......
答案 0 :(得分:18)
由于Objectify的流行,在先前版本中添加了一种解决方法来支持Key
类型,直到有更通用的解决方案可用。由于新解决方案可用,因此已删除了解决方法。现在有两种方法可以解决该属性的问题。
@ApiResourceProperty
注释,使序列化期间从对象中省略键。如果您想要一个简单的解决方案而不需要访问客户端中的密钥,请使用此方法。@ApiTransformer
注释,提供用于序列化/反序列化字段的兼容机制。如果需要访问客户端中的密钥(或其表示),请使用此方法。由于这需要编写变换器类,因此它比第一个选项更有效。答案 1 :(得分:6)
我为我的项目提出了以下解决方案:
@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;
}
我知道,它有点样板,但是嘿 - 它可以工作并添加了一些方便的快捷方法。
答案 2 :(得分:0)
起初,我不理解Flori给出的答案,它真的有用。因为其他人可能会受益,我会做一个简短的解释。
如前所述,您可以使用@ApiTransformer
为您的班级定义变换器。这会将不可序列化的字段(如Key<myClass>
类型的字段转换为其他字段,例如Long
。
事实证明,当GCE处理类时,名为get{fieldName}
和set{FieldName}
的方法会自动用于转换字段{fieldName}
。我无法在Google的文档中找到它。
以下是我在Key{Machine}
课程中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);
}
// ...
}
答案 3 :(得分:0)
其他人已经提到了如何使用@ApiResourceProperty
和@ApiTransformer
来解决此问题。但我确实需要客户端提供的密钥,而且我不想为每个密钥转换整个实体。我尝试用com.google.appengine.api.datastore.Key
替换Objectify Key,看起来它在我的情况下工作得很好,因为这里的问题主要是由于端点不支持参数化类型。