All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fasterxml.jackson.module.hibernate.HibernateProxySerializer Maven / Gradle / Ivy

Go to download

Add-on module for Jackson (http://jackson.codehaus.org) to support Hibernate (http://hibernate.org) data types.

There is a newer version: 1.9.1
Show newest version
package com.fasterxml.jackson.module.hibernate;

import java.io.IOException;

import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer;

import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.BeanProperty;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;
import org.codehaus.jackson.map.TypeSerializer;
import org.codehaus.jackson.map.ser.impl.PropertySerializerMap;

/**
 * Serializer to use for values proxied using {@link HibernateProxy}.
 *

* TODO: should try to make this work more like Jackson * BeanPropertyWriter, possibly sub-classing * it -- it handles much of functionality we need, and has * access to more information than value serializers (like * this one) have. */ public class HibernateProxySerializer extends JsonSerializer { /** * Property that has proxy value to handle */ protected final BeanProperty _property; protected final boolean _forceLazyLoading; /** * For efficient serializer lookup, let's use this; most * of the time, there's just one type and one serializer. */ protected PropertySerializerMap _dynamicSerializers; /* /********************************************************************** /* Life cycle /********************************************************************** */ public HibernateProxySerializer(BeanProperty property, boolean forceLazyLoading) { _property = property; _forceLazyLoading = forceLazyLoading; _dynamicSerializers = PropertySerializerMap.emptyMap(); } /* /********************************************************************** /* JsonSerializer impl /********************************************************************** */ @Override public void serialize(HibernateProxy value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { Object proxiedValue = findProxied(value); // TODO: figure out how to suppress nulls, if necessary? (too late for that here) if (proxiedValue == null) { provider.defaultSerializeNull(jgen); return; } findSerializer(provider, proxiedValue).serialize(proxiedValue, jgen, provider); } public void serializeWithType(HibernateProxy value, JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer) throws IOException, JsonProcessingException { Object proxiedValue = findProxied(value); if (proxiedValue == null) { provider.defaultSerializeNull(jgen); return; } /* This isn't exactly right, since type serializer really refers to proxy * object, not value. And we really don't either know static type (necessary * to know how to apply additional type info) or other things; * so it's not going to work well. But... we'll do out best. */ findSerializer(provider, proxiedValue).serializeWithType(proxiedValue, jgen, provider, typeSer); } /* /********************************************************************** /* Helper methods /********************************************************************** */ protected JsonSerializer findSerializer(SerializerProvider provider, Object value) throws IOException, JsonProcessingException { /* TODO: if Hibernate did use generics, or we wanted to allow use of Jackson * annotations to indicate type, should take that into account. */ Class type = value.getClass(); /* we will use a map to contain serializers found so far, keyed by type: * this avoids potentially costly lookup from global caches and/or construction * of new serializers */ PropertySerializerMap.SerializerAndMapResult result = _dynamicSerializers.findAndAddSerializer(type, provider, _property); if (_dynamicSerializers != result.map) { _dynamicSerializers = result.map; } return result.serializer; } /** * Helper method for finding value being proxied, if it is available * or if it is to be forced to be loaded. */ protected Object findProxied(HibernateProxy proxy) { LazyInitializer init = proxy.getHibernateLazyInitializer(); if (!_forceLazyLoading && init.isUninitialized()) { return null; } return init.getImplementation(); } }