I have a simple controller that return a User object, this user have a attribute coordinates that have the hibernate property FetchType.LAZY.
When I try to get this
As of Spring 4.2 and using Spring Boot and javaconfig, registering the Hibernate4Module is now as simple as adding this to your configuration:
@Bean
public Module datatypeHibernateModule() {
return new Hibernate4Module();
}
ref: https://spring.io/blog/2014/12/02/latest-jackson-integration-improvements-in-spring
If you use XML config and use <annotation-driven />
, I found that you have to nest <message-converters>
inside <annotation-driven>
as recommended on the Jackson Github account.
Like so:
<annotation-driven>
<message-converters>
<beans:bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<beans:property name="objectMapper">
<beans:bean class="com.pastelstudios.json.HibernateAwareObjectMapper" />
</beans:property>
</beans:bean>
</message-converters>
</annotation-driven>
`
Although this question is slightly different to this one : Strange Jackson exception being thrown when serializing Hibernate object, the underlying problem can be fixed in the same way with this code:
@Provider
public class MyJacksonJsonProvider extends JacksonJsonProvider {
public MyJacksonJsonProvider() {
ObjectMapper mapper = new ObjectMapper();
mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
setMapper(mapper);
}
}
I tried @rick's useful answer, but ran into the problem that "well-known modules" such as jackson-datatype-jsr310 weren't automatically registered despite them being on the classpath. (This blog post explains the auto-registration.)
Expanding on @rick's answer, here's a variation using Spring's Jackson2ObjectMapperBuilder to create the ObjectMapper
. This auto-registers the "well-known modules" and sets certain features in addition to installing the Hibernate4Module
.
@Configuration
@EnableWebMvc
public class MyWebConfig extends WebMvcConfigurerAdapter {
// get a configured Hibernate4Module
// here as an example with a disabled USE_TRANSIENT_ANNOTATION feature
private Hibernate4Module hibernate4Module() {
return new Hibernate4Module().disable(Hibernate4Module.Feature.USE_TRANSIENT_ANNOTATION);
}
// create the ObjectMapper with Spring's Jackson2ObjectMapperBuilder
// and passing the hibernate4Module to modulesToInstall()
private MappingJackson2HttpMessageConverter jacksonMessageConverter(){
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder()
.modulesToInstall(hibernate4Module());
return new MappingJackson2HttpMessageConverter(builder.build());
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(jacksonMessageConverter());
super.configureMessageConverters(converters);
}
}
This is similar to accepted solution by @rick.
If you don't want to touch existing message converters configuration you can just declare a Jackson2ObjectMapperBuilder
bean like:
@Bean
public Jackson2ObjectMapperBuilder configureObjectMapper() {
return new Jackson2ObjectMapperBuilder()
.modulesToInstall(Hibernate4Module.class);
}
Do not forget to add the following dependency to your Gradle file (or Maven):
compile 'com.fasterxml.jackson.datatype:jackson-datatype-hibernate4:2.4.4'
Useful if you have a spring-boot application and you want to keep the ability to modify Jackson features from application.properties
file.
Another solution for spring boot:
configuration:
spring.jpa.open-in-view=true