【发布时间】:2013-06-07 03:43:41
【问题描述】:
我试图了解为什么我在某些 GET 调用中收到错误,而在其他 Google App Engine 实体中却没有。
类
@Entity
public class Client {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Key id;
private String firstName;
private String lastName;
@Basic(fetch = FetchType.EAGER)
@ElementCollection
private List<Assessment> assessment;
public List<Assessment> getAssessment() {
return assessment;
}
public void setAssessment(List<Assessment> assessment) {
this.assessment = assessment;
}
}
作品
如果我使用list 请求,它工作正常。
GET http://localhost:8888/_ah/api/clientendpoint/v1/client
结果如预期
{
"items": [
{
"id": {
"kind": "Client",
"appId": "no_app_id",
"id": "12",
"complete": true
},
"firstName": "Jane",
"lastName": "Doe"
},
{
"id": {
"kind": "Client",
"appId": "no_app_id",
"id": "13",
"complete": true
},
"firstName": "Jon",
"lastName": "Doe",
}
]
}
不起作用
但如果我只得到 1 条记录,例如选择 id 12,则会产生错误
GET http://localhost:8888/_ah/api/clientendpoint/v1/client/12
com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingException: 您刚刚尝试访问字段“评估”但此字段 分离对象时未分离。要么不要访问这个 字段,或在分离对象时将其分离。 (通过参考 链: com.google.api.server.spi.response.CollectionResponse[\"items\"]->com.google.appengine.datanucleus.query.StreamingQueryResult[0]->com.my.app.client.Client[\"评估\"])
如果我删除 get/set 方法就可以使用
我感到困惑的是,如果我在 Client 对象中注释掉 setAssessment(...) 和 getAssesment() 方法,它可以正常工作。
@Entity
public class Client {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Key id;
private String firstName;
private String lastName;
@Basic(fetch = FetchType.EAGER)
@ElementCollection
private List<Assessment> assessment;
//public List<Assessment> getAssessment() {
// return assessment;
//}
//public void setAssessment(List<Assessment> assessment) {
// this.assessment = assessment;
//}
}
效果很好
GET http://localhost:8888/_ah/api/clientendpoint/v1/client/12
结果
{
"id": {
"kind": "Client",
"appId": "no_app_id",
"id": "12",
"complete": true
},
"firstName": "Jane",
"lastName": "Doe"
}
我的问题是
- 为什么当我注释掉 get/set 时它会起作用
- 如何正确解决此问题?
- 除了文档中的简单示例之外,我无法为 Java App Engine 代码找到好的代码示例。有人知道什么好的例子吗?
相关端点代码
/**
*
* This method works fine
*
*/
@SuppressWarnings({ "unchecked", "unused" })
@ApiMethod(name = "listClient")
public CollectionResponse<Client> listClient(
@Nullable @Named("cursor") String cursorString,
@Nullable @Named("limit") Integer limit) {
EntityManager mgr = null;
Cursor cursor = null;
List<Client> execute = null;
try {
mgr = getEntityManager();
Query query = mgr.createQuery("select from Client as Client");
if (cursorString != null && cursorString != "") {
cursor = Cursor.fromWebSafeString(cursorString);
query.setHint(JPACursorHelper.CURSOR_HINT, cursor);
}
if (limit != null) {
query.setFirstResult(0);
query.setMaxResults(limit);
}
execute = (List<Client>) query.getResultList();
cursor = JPACursorHelper.getCursor(execute);
if (cursor != null)
cursorString = cursor.toWebSafeString();
} finally {
mgr.close();
}
return CollectionResponse.<Client> builder().setItems(execute)
.setNextPageToken(cursorString).build();
}
/**
*
* This method errors out
*
*/
@ApiMethod(name = "getClient")
public Client getClient(@Named("id") Long id) {
EntityManager mgr = getEntityManager();
Client client = null;
client = mgr.find(Client.class, id);
mgr.close();
return client;
}
【问题讨论】:
-
从表面上看,这似乎又是延迟加载的问题,但我不确定。您是否在您的任何实体中将
assessment设置为非空值?它没有在您的示例list调用中显示值,我只是想确保它是准确的。 -
我还没有在
assessment中输入任何内容。并非所有实体都会拥有它们。我需要在构造函数内部初始化assessment吗? -
不,我只是检查您的
list调用中缺少assessments 不是错误。我将不得不尝试一下以找出问题所在。
标签: java google-app-engine rest google-cloud-storage google-cloud-endpoints