При сериализации объекта Hibernate выдается странное исключение Джексона - PullRequest
61 голосов
/ 06 декабря 2010

Джексон выбрасывает странное исключение, которое я не знаю, как исправить.Я использую 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$1.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)

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

РЕДАКТИРОВАТЬ: Я обнаружил, что getHander () и другие методы get * () существуют на прокси-объекте.GRR !!Можно ли как-то сказать Джексону, чтобы он ничего не обрабатывал на прокси, или я сол?Это действительно странно, потому что метод, который выплевывает JSON, падает только при определенных обстоятельствах, а не постоянно.Тем не менее, это связано с методами get * () прокси-объекта.

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

Ответы [ 15 ]

69 голосов
/ 04 января 2011

У меня была похожая проблема с отложенной загрузкой через прокси-объект hibernate. Обошли его, добавив аннотации к классу с lazyloaded частными свойствами:

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

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

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

38 голосов
/ 06 декабря 2010

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

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

23 голосов
/ 21 ноября 2011

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

Добавление методов получения и установки решило проблему.

9 голосов
/ 07 декабря 2010

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

6 голосов
/ 29 марта 2012

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

5 голосов
/ 25 апреля 2014

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

4 голосов
/ 10 февраля 2014

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

3 голосов
/ 17 октября 2016

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

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

После того, как:

@ManyToOne(targetEntity = StatusCode.class, fetch = FetchType.EAGER)
2 голосов
/ 24 мая 2017

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

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


@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
private abstract class IgnoreHibernatePropertiesInJackson{ }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...