2012-08-15 70 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();  

} 

将导致该错误,返回更新的对象不。