2012-08-15 27 views
1

我正在開發一個Android應用程序,與GAE服務器+ Objectify DB通信。JsonMappingException:如何通過Restlet傳遞一個Objectify實體(帶密鑰)

我選擇Restlet作爲rest框架。

我嘗試使用鍵屬性檢索實體時出現問題。服務器拋出一個錯誤:

org.codehaus.jackson.map.JsonMappingException: Direct self-reference leading to cycle 
(through reference chain: java.util.ArrayList[0]->com.my.model.MyMessage["senderKey"]->com.googlecode.objectify.Key["root"]) 

這裏是我的模型(很簡單):

public class MyMessage implements Serializable { 
private static final long serialVersionUID = -1075184303389185795L; 

@Id 
private Long id; 

@Unindexed 
private String sendMessage; 

@Parent 
Key<MyUser> senderKey; 

private MyMessage() { 
} 

public MyMessage(MyUser user, String message) { 
    super(); 
    this.sendMessage = message; 
    this.senderKey = new Key<MyUser>(MyUser.class, user.getId()); 
} 

[... getters and setters ...] 
} 

public class MyUser implements Serializable { 

private static final long serialVersionUID = 7390103290165670089L; 
@Id private String id; 

private MyUser() { 
    this.setId("default"); 
} 

public MyUser(String mail) { 
    this.setId(mail); 
} 
[... getters and setters ...] 

}

我能做些什麼來解決這個問題?

回答

2

Objectify的Key有一個方便的方法getRoot(),它返回祖先鏈中的根元素。當一個密鑰的根時,getRoot()返回這個。傑克遜發現這是一個循環,因此你會得到錯誤。

處理此問題的最佳方法不是嘗試將Keys序列化爲json對象。在JSON中,鍵被更好地表示爲串化版本。

我不知道你在Restlet中如何做到這一點,但是你需要修改ObjectMapper實例來提供一個做這種轉換的KeySerializer。看看Objectify4的ObjectifyJacksonModule指導:

https://code.google.com/p/objectify-appengine/source/browse/src/com/googlecode/objectify/util/jackson/ObjectifyJacksonModule.java

+0

爲什麼我不能爲我的密鑰添加'瞬態'?我試過但我仍然得到相同的錯誤.... – Tyvain 2012-09-04 23:46:03

+0

我也試過@JsonIgnore,但它不工作... – Tyvain 2012-09-05 23:24:45

+0

要麼隱藏Jackson的senderKey字段,要麼找出如何自定義Restlet使用的ObjectMapper,以便它序列化鍵作爲它們的字符串屬性。我不知道爲什麼@JsonIgnore沒有工作,但這是一個傑克遜問題 - 可能與您放置註釋的位置(字段,getter等)有關。 – stickfigure 2012-09-06 06:42:36

0

是否包含

<inherits name="com.googlecode.objectify.Objectify" /> 

你的GWT模塊中?

+0

我不使用GWT。 – Tyvain 2012-09-05 23:01:20

0

我有導致這種確切的錯誤了類似的問題。將代碼減少到絕對必要性後,我發現如果從AppEngine API方法返回Key對象,我會看到這個錯誤。

@ApiMethod(name = "insertPureContainer", path="insertPureContainer", httpMethod = ApiMethod.HttpMethod.POST) 
public Key insertPureContainer(PureContainer container, User user) throws OAuthRequestException { 

    return ofy().save().entity(container).now();  

} 

將導致該錯誤,返回更新的對象不。