Странное исключение Джексона выбрасывается при сериализации объекта Hibernate



Джексон бросает странное исключение, которое я не знаю как исправить. Я использую Spring, Hibernate и Jackson.



Я уже считал, что ленивая загрузка вызывает проблему, но я принял меры, чтобы сказать Джексону не обрабатывать различные свойства следующим образом:



@JsonIgnoreProperties({ "sentMessages", "receivedMessages", "educationFacility" })
public class Director extends UserAccount implements EducationFacilityUser {
....
}


Я сделал то же самое для всех других подклассов UserAccount, а также.



вот исключение выбрасывается:



org.codehaus.jackson.map.JsonMappingException: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: java.util.ArrayList[46]->jobprep.domain.educationfacility.Director_$$_javassist_2["handler"])
at org.codehaus.jackson.map.ser.StdSerializerProvider.serialize(StdSerializerProvider.java:62)
at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:268)
at org.codehaus.jackson.map.ser.BeanSerializer.serializeFields(BeanSerializer.java:146)
at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:118)
at org.codehaus.jackson.map.ser.ContainerSerializers$IndexedListSerializer.serializeContents(ContainerSerializers.java:236)
at org.codehaus.jackson.map.ser.ContainerSerializers$IndexedListSerializer.serializeContents(ContainerSerializers.java:189)
at org.codehaus.jackson.map.ser.ContainerSerializers$AsArraySerializer.serialize(ContainerSerializers.java:111)
at org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:296)
at org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:224)
at org.codehaus.jackson.map.ObjectMapper.writeValue(ObjectMapper.java:925)
at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.writeInternal(MappingJacksonHttpMessageConverter.java:153)


предложения о том, как я может получить дополнительную информацию, чтобы увидеть, что вызывает это? Кто-нибудь знает как это исправить?



EDIT: я обнаружил, что getHander() и другие методы get*() существуют на прокси-объекте. ГРР!! Есть ли способ сказать Джексону, чтобы он ничего не обрабатывал на прокси, или я Сол? Это действительно странно, потому что метод, который выплевывает JSON, только падает при определенных обстоятельствах, а не все время. Тем не менее, это связано с методами get*() на прокси объект.



в сторону: прокси-это зло. Они нарушают Джексон, equals () и многие другие части регулярного программирования Java. Я испытываю искушение полностью погрузиться в спячку:/

1140   15  

15 ответов:

это не идеально, но вы можете отключить автоматическое обнаружение Джексоном свойств JSON, используя @JsonAutoDetect на уровне класса. Это помешало бы ему пытаться обрабатывать Javassist вещи (и не удается).

Это означает, что вы должны комментировать каждый геттер вручную (с @JsonProperty), но это не обязательно плохо, так как он держит вещи явные.

У меня была аналогичная проблема с ленивой загрузкой через прокси-объект hibernate. Обошел его, аннотируя класс, имеющий lazyloaded private properties с помощью:

@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})

Я предполагаю, что вы можете добавить свойства вашего прокси-объекта, который нарушает сериализацию JSON в эту аннотацию.

избегайте сериализации Джексона на не извлеченных ленивых объектах

Я получил ту же ошибку, но без отношения к Hibernate. Я испугался здесь от всех пугающих предложений, которые, я думаю, актуальны в случае спячки и ленивой загрузки... Однако в моем случае я получил ошибку, так как во внутреннем классе у меня не было геттеров/сеттеров, поэтому BeanSerializer не мог сериализовать данные...

добавление геттеров и сеттеров решило проблему.

для чего это стоит, есть модуль гибернации Джексона проект, который только что начался, и который должен решить эту проблему и, надеюсь, другие, а также. Проект связан с проектом Джексона, хотя и не является частью основного источника. Это в основном позволяет упростить процесс выпуска; для этого потребуется Jackson 1.7, так как именно тогда вводится API модуля.

у меня была та же проблема. Смотрите, если вы используете hibernatesession.load(). Если это так, попробуйте преобразовать в hibernatesession.get(). Это решило мою проблему.

у меня было такое же сообщение об ошибке с весны @RestController. Мой класс контроллера rest использовал spring's JpaRepository класс и путем замены repository.getOne(id) вызов метода с repository.findOne(id) проблема исчезла.

вы можете использовать модуль jackson-datatype-hibernate для решения этой проблемы. Это работает на меня. ссылка: https://github.com/FasterXML/jackson-datatype-hibernate

Как и другие ответы, проблема для меня заключалась в объявлении столбца "многие к одному" для выполнения ленивой выборки. Переход на нетерпеливую выборку исправил проблему. Раньше:

@ManyToOne(targetEntity = StatusCode.class, fetch = FetchType.LAZY)

после:

@ManyToOne(targetEntity = StatusCode.class, fetch = FetchType.EAGER)

вы могли бы использовать @JsonIgnoreProperties(value = { "handler", "hibernateLazyInitializer" }) аннотация на вашем классе "директор"

вы можете добавить Джексон миксин на объект.класс, чтобы всегда игнорировать свойства, связанные с гибернацией. Если вы используете Spring Boot, поместите это в свой класс приложений:

@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder() {
    Jackson2ObjectMapperBuilder b = new Jackson2ObjectMapperBuilder();
    b.mixIn(Object.class, IgnoreHibernatePropertiesInJackson.class);
    return b;
}


@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
private abstract class IgnoreHibernatePropertiesInJackson{ }

Я новичок в Jackson API, когда я получил " org.codehaus.Джексон.карта.JsonMappingException: сериализатор для класса com не найден.компания.проект.yourclass", я добавил геттер и сеттер в com.компания.проект.yourclass, который помог мне использовать объект mapper ObjectMapper для записи объекта java в плоский файл.

Я столкнулся с той же проблемой, и это действительно странно, что один и тот же код работает в нескольких случаях, тогда как это не удалось в некоторых случайных случаях.

я исправил это, просто убедившись, что правильный сеттер / геттер (убедившись, что чувствительность к регистру)

пробовал @JsonDetect и

@JsonIgnoreProperties(value = { "handler", "hibernateLazyInitializer" })

ни один из них не работал для меня. Использование стороннего модуля казалось мне большой работой. Так что я просто попытался сделать get вызовите любое свойство ленивого объекта перед передачей в jackson для serlization. Рабочий фрагмент кода выглядел примерно так:

@RequestMapping(value = "/authenticate", produces = "application/json; charset=utf-8")
    @ResponseBody
    @Transactional
    public Account authenticate(Principal principal) {
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = (UsernamePasswordAuthenticationToken) principal;
        LoggedInUserDetails loggedInUserDetails = (LoggedInUserDetails) usernamePasswordAuthenticationToken.getPrincipal();
        User user = userRepository.findOne(loggedInUserDetails.getUserId());
        Account account = user.getAccount();
        account.getFullName();      //Since, account is lazy giving it directly to jackson for serlization didn't worked & hence, this quick-fix.
        return account;
    }

Также Вы можете сделать ваш директор объекта домена окончательный. Это не идеальное решение, но оно предотвращает создание прокси-подкласса вашего доменного класса.

Comments

    Ничего не найдено.