3

In my Spring 4 project with Hibernate 5 and Java-based configuration I keep facing exception "could not initialize proxy - no Session " every time Jackson tries to serialize my entity with a lazy collection. It seems Jackson fails to check if collection is lazy and triggers loading which generates the exception. How do I make Jackson avoid serialization of every lazy-loaded collection on every @Entity-class and thus avoid constant exceptions and fails with "no Session"? The simplest working solution. I've read many approaches neighter of which really solves this problem for me. Any help will be appreciated (not for Spring Boot!). Some code snippet:

@Data
@Entity
@ToString(exclude="questions")
@Table(name = "theme")
public class Theme {

    @Id
    @GeneratedValue(generator = "increment")
    @GenericGenerator(name = "increment", strategy = "increment")
    @Column(name = "id")
    private Long id;

    @Column(name = "title")
    private String title;

    @JsonInclude(JsonInclude.Include.NON_NULL)
    @OneToMany // LAZY by default
    @JoinColumn(name = "theme")
    private List<Question> questions;// = new ArrayList<>();
}

DAO

public interface ThemeDAO extends CrudRepository<Theme, Long> {
    List<Theme> findAll();
}

Exception goes here (in controller):

 ObjectMapper objectMapper = new ObjectMapper();
 result = objectMapper.writeValueAsString(theme);
Andreas Gelever
  • 1,736
  • 3
  • 19
  • 25
  • You can use `@JsonIgnore` – gaganbm Apr 05 '17 at 13:25
  • Yes I know. But I sometimes need to retrieve this collection , e.g. I need it to work smoothly: @Query("SELECT t FROM Theme t LEFT JOIN FETCH t.questions WHERE t.id=?1") Theme findOneWithQuestions(Long id); And that annotation will prevent me from doing this forever. – Andreas Gelever Apr 05 '17 at 13:39
  • 1
    Have you looked at the [hibernate module](https://github.com/FasterXML/jackson-datatype-hibernate)? – Nicolas Labrot Apr 05 '17 at 13:41
  • Yes, I found this add-on https://mvnrepository.com/artifact/com.fasterxml.jackson.datatype/jackson-datatype-hibernate5. It seems to be the exact tool for it. But I found it has got few usages and deduced it is not very popular smehow. – Andreas Gelever Apr 05 '17 at 13:50
  • Possible duplicate of [Avoid Jackson serialization on non fetched lazy objects](http://stackoverflow.com/questions/21708339/avoid-jackson-serialization-on-non-fetched-lazy-objects) – Alex Ciocan Apr 05 '17 at 15:09

1 Answers1

2

jackson-datatype-hibernate add-on really solved the problem. I just added HibernateAwareObjectMapper as a separate class:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module;
public class HibernateAwareObjectMapper extends ObjectMapper {

    public HibernateAwareObjectMapper() {
            registerModule(new Hibernate5Module());
    }

}

And then overrode the method configureMessageConverters in MVC configurer class:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "learning_session.controller" })
public class WebContext extends WebMvcConfigurerAdapter implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    public void setApplicationContext(ApplicationContext applicationContext) {
            this.applicationContext = applicationContext;
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
            converters.add(new MappingJackson2HttpMessageConverter(new HibernateAwareObjectMapper()));
            super.configureMessageConverters(converters);
    }
// more beans 
}
Andreas Gelever
  • 1,736
  • 3
  • 19
  • 25