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 для руководства:
Вы включили
<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();
}
Будет приводить к этой ошибке, возвращать обновленный объект не будет.