My environment
- jackson-datatype-hibernate 2.3.2
- Spring-webmvc 3.2.6
- Hibernate 4.3.4
So basically my application is supposed to return a list of serialized corporations. The corporation class has a set of traveller objects which are lazy loaded(lazy='true' defined in mapping). Consequently they shouldn't be serialized. However, when jackson is serializing the corporations from the controller, for some reason, it also tries to serialize travellers, but it crashes and throws an error: org.hibernate.LazyInitializationException - failed to lazily initialize a collection of role: com.model.core.Corporation.employees
I have googled this issue and I've seen it in a couple of posts but I haven't been able to fix it so far. https://github.com/FasterXML/jackson-datatype-hibernate/issues/25
My code is basically composed of a java "Corporation" class with its hbm.xml mapping. I've also extended the ObjectMapper and set it to the Spring message converter as told in that post (Avoid Jackson serialization on non fetched lazy objects) Then I created a "CorporationMixin" class and annotated it with @JsonIdentityInfo. To finish, I just return the list of corporations from the controller.
Please have a look at my code and give me a hint. I don't know whether the problem is my implementation or a bug in the jackson-datatype-hibernate library.
Mapping hbm :
<class name="com.model.core.Corporation" table="corporation" lazy="false">
<id name="id" column="corporation_id" type="java.lang.String" unsaved-value="0">
<generator class="guid"/>
</id>
<set lazy="true" name="employees" inverse="false" cascade="delete">
<key column="corporation_id"/>
<one-to-many class="com.model.core.Employee"/>
</set>
...
</class>
"Corporation" entity:
public class Corporation implements Serializable
{
private String id;
private Set<Employee> employees;
...(get/set)
}
Mapper added to servlet-context.xml:
<mvc:annotation-driven >
<mvc:message-converters>
<!-- Use the HibernateAware mapper instead of the default -->
<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="com.mapper.HibernateAwareObjectMapper" />
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
HibernateAwareObjectMapper class:
public class HibernateAwareObjectMapper extends ObjectMapper {
public HibernateAwareObjectMapper() {
registerModule(new Hibernate4Module());
this.addMixInAnnotations(Corporation.class, CorporationMixin.class);
}
}
CorporationMixin class:
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
public abstract class CorporationMixin {
}
Controller class which returns the serialized corporations:
@RequestMapping(value="/secured/corporations/init",method = RequestMethod.GET,produces = "application/json")
@ResponseBody
public ResponseEntity<List<Corporation>> getUsersList()
{
List<Corporation> corps = corporationDao.getTopCorporations();
return new ResponseEntity<List<Corporation>>(corps, HttpStatus.OK);
}
There's a workaround to avoid the crash of hibernate which is basically adding this in web.xml
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>false</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
But that doesn't really fix the initial issue which is why jackson tries to serialize collections whose lazy=true??
Thanks for your help!