2016-06-07 4 views
2

Я работаю над проектом, использующим Hibernate и Jackson для сериализации моих объектов. Думаю, я понимаю, как это работает, но я не могу заставить его работать.Hibernate и Jackson lazy serialization

Если я хорошо понимаю, как только режим выборки отношений установлен в LAZY, если вы хотите это отношение, вы должны его инициализировать.

Вот мой класс:

@Entity 
@JsonIgnoreProperties(ignoreUnknown = true) 
@Table(schema="MDDI_ADMIN", name = "MINIUSINE") 
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE) 
public class MiniUsine { 

    @Id 
    @Column(name="MINIUSINEID", nullable = false) 
    private int miniUsineID; 

    @Column(name = "NAME", length = 40, nullable = false) 
    private String name; 

    @OneToMany(cascade = CascadeType.ALL) 
    @JoinColumn(name="FluxID") 
    @JsonInclude(JsonInclude.Include.NON_EMPTY) 
    private Set<Flux> fluxs = new HashSet<Flux>(); 

И все методы получения и установки.

Я также пробовал это JsonInclude.Include.NON_EMPTY в качестве аннотации класса. Также попробовал NON_NULL. Однако джексон продолжает посылать мне

com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: MiniUsine.fluxs, no session or session was closed (through reference chain: java.util.ArrayList[0]->MiniUsine["fluxs"])

Я сериализации с: mapper.writeValueAsString(optMU);

Использование Джексон 2.3.2

Спасибо за помощь

ответ

3

Насколько я понимаю, объект объекта, который возвращает hibernate, является прокси-сервером, который является производным от вашего класса сущности. Если вы попытаетесь получить доступ к методам getter для ленивых полей вне транзакции, вы получите LazyInitializationException. Точка, которую я хочу сделать, это установка флюсов в пустой набор, который вам совсем не помогает.

private Set<Flux> fluxs = new HashSet<Flux>(); 

Hibernate перегружает поглотитель и, если вы пытаетесь получить доступ к нему за пределами сделки (которая джексон делает для того чтобы проверить, если он пуст), вы получите сообщение об ошибке LazyInit.

+0

Но он не должен обращаться к нему, когда он пуст (когда я его не инициализирую) из-за '@JsonInclude (JsonInclude.Include.NON_EMPTY)' Я никогда не получаю доступ к нему сам, только Джексон хочет получить доступ это при сериализации объекта – xNeyte

+0

@JsonInclude (JsonInclude.Include.NON_EMPTY) означает включение этого поля, только если оно не пустое. Но чтобы проверить, нужно ли его пустое, Джексону нужно вызвать .isEmpty() в коллекции? Однако эта коллекция не является пустой hash_set, которую вы предоставили. Он предоставляется спящим режимом. И этот вызов произойдет за пределами транзакции, что приведет к ошибке. – saby

+0

Поскольку fetchmode LAZY, сбор не должен быть загружен, если я его не инициализирую, поэтому он должен быть пустым, когда джексон проверяет его :( – xNeyte

0

Существует jackson data type, где поддерживается аннотация hibernate. Он игнорирует ленивый загруженный список по умолчанию.

0

Я знаю, что это старый вопрос, но у меня была та же проблема.

Вы должны добавить новый maven dependecy для поддержки сериализации JSON и десериализации Hibernate. Я использовал Hibernate5, поэтому добавил

<dependency> 
    <groupId>com.fasterxml.jackson.datatype</groupId> 
    <artifactId>jackson-datatype-hibernate5</artifactId> 
    <version>2.9.2</version> 
</dependency> 

Теперь зарегистрируйте новый модуль.

@Provider 
public class JacksonHibernateProvider implements ContextResolver<ObjectMapper> { 

    @Override 
    public ObjectMapper getContext(final Class<?> type) { 
     final ObjectMapper mapper = new ObjectMapper(); 
     mapper.registerModule(new Hibernate5Module()); 
     return mapper; 
    } 
} 

И все. Надеюсь это поможет.