Mit Jackson Hibernate Datentypen nach JSON serialisieren (Spring)

Um Java-Objekte in JSON umzuwandeln, kann man die Jackson Library verwenden. Will man aber Hibernate-Objekte damit serialisieren, bekommt man z.B. bei lazy-geladenen Eigenschaften Probleme, da Jackson damit nicht umgehen kann. Typischerweise hat man eine Fehlermeldung wie „could not initialize proxy – no Session“.

Damit Jackson auch mit Hibernate-Objekten korrekt umgehen kann, muß man deren Add-on Modul jackson-datatype-hibernate verwenden:

Die Verwendung funktioniert folgendermaßen:

  • Maven dependency hinzufügen (in <version> die aktuelle Version angeben, momentan 2.8.8)
<dependency>
  <groupId>com.fasterxml.jackson.datatype</groupId>
  <artifactId>jackson-datatype-hibernate4</artifactId>
  <version>2.8.8</version>
</dependency>
  • eine neue Object-Mapper Klasse erstellen, den Jackson Object-Mapper erweitern und dort das Modul registrieren
public class HibernateAwareObjectMapper extends ObjectMapper {
    public HibernateAwareObjectMapper() {
        registerModule(new Hibernate4Module());
    }
}
  • in der Spring Konfiguration diesen Object-Mapper einstellen
	<bean id="objectMapper" class="path.to.your.HibernateAwareObjectMapper"></bean>

	<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
		<property name="messageConverters">
			<array>
				<bean id="jsonConverter"
					class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
					<property name="objectMapper" ref="objectMapper"></property>
				</bean>
			</array>
		</property>
	</bean>

Nun werden Lazy-loaded Objekte standardmäßig als null serialisiert. Man kann aber auch einstellen, dass diese automatisch nachgeladen werden sollen:

public class HibernateAwareObjectMapper extends ObjectMapper {
    public HibernateAwareObjectMapper() {
        Hibernate4Module hibernate4Module = new Hibernate4Module();
        hibernate4Module.enable(Hibernate4Module.Feature.FORCE_LAZY_LOADING);
        registerModule(hibernate4Module);
    }
}