JsonMappingException: как передать объект Objectify (с ключом) через рестлет

Я разрабатываю приложение для Android, соединяясь с сервером GAE + Objectify DB.

Я выбираю Рестлет для рамок отдыха.

У меня проблема при попытке получить сущность с атрибутом Key. Сервер выдает ошибку:

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 ...]

}

Что я могу сделать, чтобы решить эту проблему?

3 ответа

Решение

Ключ Objectify имеет удобный метод getRoot(), который возвращает корневой элемент в цепочке предков. Когда ключ является корнем, getRoot() возвращает это. Джексон обнаруживает это как цикл, и поэтому вы получаете ошибку.

Лучший способ справиться с этим - не пытаться сериализовать ключи как объекты json. Ключи гораздо лучше представлены в JSON в виде строковой версии.

Я не знаю, как вы делаете это в Restlet, но вам нужно изменить экземпляр ObjectMapper, чтобы обеспечить KeySerializer, который выполняет этот перевод. Посмотрите на ObjectifyJacksonModule в Objectify4 для руководства:

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

Вы включили

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

в вашем модуле GWT?

У меня была похожая проблема, которая привела к этой точной ошибке. Сокращая код до его абсолютной необходимости, я обнаружил, что увижу эту ошибку, если верну объект Key из метода API AppEngine.

т.е.

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

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

}

Будет приводить к этой ошибке, возвращать обновленный объект не будет.

Другие вопросы по тегам