4

Good day all, I have spent considerable time Googlin' and upgrading from JSON 1 to JSON 2 but when I try and return a list of entities, I get the exception:

"Received Exception Could not write JSON: could not initialize proxy - no Session (through reference chain:"

I know this is related to Hibernate lazy init but I haven't figured out how to fix it. I thought the jackson-module-hibernate project was the solution. However I haven't been able to make it work.

Here is my tech:

  • Spring: 3.2.1RELEASE
  • Hibernate 4.1.7.Final
  • Jackson 2
  • jackson-core 2.0.4
  • jackson-databind: 2.0.4
  • jackson-datatype-hibernate4: 2.1.2

I am using Java Config: ...

@Bean
public com.mycompany.config.MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
    MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
    mappingJackson2HttpMessageConverter.setObjectMapper(new HibernateAwareObjectMapper());
    return mappingJackson2HttpMessageConverter;
}

@Bean 
public OpenEntityManagerInViewFilter springOpenEntityManagerInViewFilter() {
return new org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter();
}

@Bean
public ContentNegotiatingViewResolver contentNegotiatingViewResolver() {
final ContentNegotiatingViewResolver contentNegotiatingViewResolver = new ContentNegotiatingViewResolver();
contentNegotiatingViewResolver.setDefaultContentType(MediaType.APPLICATION_JSON);
final ArrayList defaultViews = new ArrayList();
defaultViews.add(converter());
contentNegotiatingViewResolver.setDefaultViews(defaultViews);
   return contentNegotiatingViewResolver;
}

I also have:

public class HibernateAwareObjectMapper extends ObjectMapper {

public HibernateAwareObjectMapper() {
    Hibernate4Module hm = new Hibernate4Module();
    registerModule(hm);
}
}

The flow starts from the controller, which calls several services that each return an entity or List. I then put the returned objects into a object and return it, thinking the @ResponseBody will work. However, I must not have things wired right since I still get the exceptions.

Can anyone see any errors here?

Gratefully...

2 Answers 2

3

This is resolved in 2.5.0 version of jackson-datatype-hibernate. Just pass Hibernate SessionFactory in Hibernate(3,4)Module as follows:

public class HibernateAwareObjectMapper extends ObjectMapper {

private static final long serialVersionUID = 1L;

@Autowired
private EntityManagerFactory emf;

@PostConstruct
public void init() {
    Hibernate4Module module = new Hibernate4Module(emf.unwrap(SessionFactory.class));

    module.enable(Hibernate4Module.Feature.FORCE_LAZY_LOADING);
    module.disable(Hibernate4Module.Feature.USE_TRANSIENT_ANNOTATION);
}}

Above snippet is fine if JPA is in use, so EntityManagerFactory bean is available. Otherwise, just inject Hibernate SessionFactory and pass to constructor.

No need to use OpenSessionInView pattern.

Sign up to request clarification or add additional context in comments.

1 Comment

Awesome. Works from hibernate 4, jpa 2.0 with datatype 2.6.0. But instead of emf.unwrap you should use EntityManager.unwrap(HibernateEntityManager.class).getSession().getSessionFactory(), because emf.unwrap is available only since jpa 2.1 (didn't check it though).
0

It is because the object you are trying to serialize has lazy loaded component, you can add OpenSessionInViewFilter to your web configuration to fix this problem.

The hibernate session used to load the object gets closed when the execution exists the transaction, so when the view layer(jackson) tries to serialize the object and tries to load the lazy loaded objects it fails with this error.

Add this in your web.xml

<filter>
    <filter-name>hibernateFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>hibernateFilter</filter-name>
    <url-pattern>/app/*</url-pattern>
</filter-mapping>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.