У меня есть аннотированный класс, который реализует интерфейс со свойством только для чтения с именем .id()
, которое является универсальным, поэтому я могу извлекать различные типы id в других частях программы.
Джексон должен игнорировать весь этот интерфейс. Но вместо этого я получаю следующее сообщение об ошибке:
java.util.concurrent.ExecutionException
:com.fasterxml.jackson.databind.exc.InvalidDefinitionException
: Невозможно создать экземплярmy.company.Identifiable
(создатели, как и конструкции по умолчанию, не существуют): абстрактные типы либо должны быть сопоставлены с конкретными типами, иметь настраиваемый десериализатор или содержать дополнительную информацию о типе в [Источник: НЕИЗВЕСТНО; строка: -1, столбец: -1] (через цепочку ссылок:java.util.HashSet[0]
)
Я пробовал все найденные здесь решения при поиске этого исключения, а также все первые две страницы из Google. Ни один из них не решает точную проблему, с которой я сталкиваюсь, и я не смог найти решение для моей конкретной проблемы ни от одного из них, за исключением CustomDeserializer
, который я бы предпочел не писать.
Я пытался использовать JsonTypeInfo
, но мне никогда раньше не приходилось использовать эту аннотацию, и я не могу понять, что я должен с ней делать. Используемые решения немного отличаются от моих, где они на самом деле требуют свойство интерфейса, а не игнорируют его.
В некоторых классах нет фактической переменной-члена id
, это просто method
для возврата чего-то, что считается id
для другой части программы. ID<String>
в одних случаях и ID<Integer>
в других.
Я пробовал аннотировать с помощью @JsonProperty(access = Access.READ_ONLY)
, а также @JsonIgnore
и @JsonIgnoreProperties({"id"})
, ни один из них не меняет исключения. Я также пробовал все настройки mode
в @JsonCreator
, ничего не сработало.
Интерфейс определяется как:
@JsonIgnoreProperties({"id"})
public interface Identifiable<T>
{
@JsonIgnore
public T id();
}
Пример класса определяется как:
@JsonIgnoreProperties(ignoreUnknown = true)
public class User implements Identifiable<ID<String>>
{
@JsonCreator
public User(@JsonProperty("LoginName") final String loginName,
@JsonProperty("Title") final String name,
@JsonProperty("Email") final String email)
/* lots of irrelevant code redacted */
@JsonIgnore
@Override
public ID<String> id()
{
return new ID.from(this.name);
}
}
Вот как выглядит код привязки:
final HttpResponse response = req.execute();
final JsonNode root = this.om.readTree(response.getContent());
final JsonNode results = root.get("d").get("results");
final Set<V> values = this.om.readValue(this.om.treeAsTokens(results),
new TypeReference<Set<V>>() {});
Где V
— это User
в данном случае, а results
— это Array
.
Десериализация этого и пары других классов работала нормально до того, как я добавил интерфейс Identifiable<T>
, все они сломались с одним и тем же исключением.
Это не класс abstract
, каждый метод реализован. Я думаю, что поставил @JsonIgnore
везде, где это применимо.
Я все еще получаю это исключение и не знаю, как его решить.
У меня есть ощущение, что в аннотации @JsonTypeInfo
есть что-то, что может это исправить, но примеры и javadoc не написаны для тех, кто еще не знает, когда и как использовать аннотацию.
id
transient
? - person Elliott Frisch   schedule 21.09.2017id
, это простоmethod
для возврата чего-то, что считаетсяid
для другой части программы.ID<String>
в одних случаях иID<Integer>
в других. Я изменил пример, чтобы показать этот случай. - person   schedule 21.09.2017V
является переменной типа, котораяextends Identifiable<Something>
? И это связано сUser
на каком-то месте вызова? В этом случаеTypeReference
не может захватитьUser
. Взлом токена типа захватывает фактический тип в исходном коде, который в данном случае будетV
, из которого он будет извлекать любые общие границы и использовать их в меру своих возможностей. См. это и подобное для Gson это - person Sotirios Delimanolis   schedule 21.09.2017V
этоUser
, это рабочая версия, в которойUser
было везде, где сейчасV
. Я обобщил его, чтобы попробовать и использовать повторно, потому что мне нужно около дюжины классов, которые делают то же самое, за исключением типов. - person   schedule 21.09.2017new TypeReference<Set<User>>
(и некоторые другие базовые предположения), ваш образец прекрасно анализирует JSON. ЕслиV
является переменной типа (переменная общего типа метода или класс), она не будет, и я получаю описанное вами исключение (по причинам, которые я описал в своих предыдущих комментариях). Как всегда, этот минимально воспроизводимый пример имеет решающее значение :) - person Sotirios Delimanolis   schedule 21.09.2017Identifiable<T>
и получил, как мне кажется, гораздо лучший дизайн. Избегание наследования всегда является лучшим способом сделать что-то. - person   schedule 21.09.2017