问题
I am working on a Java EE 6.0 RESTful app and I am using Hibernate. I need to de-proxy my lazy loaded objects(actually the lazy loaded entity properties of an entity) before serialization to avoid the LazyInitializationException. I have done this with AMF services successfully by coding some utility that does just that before serializing the entity.
I am using the Jersey JAX-RS implementation and I need to do this with Jackson. I have found a spot in the BeanSerializer where I believed the de-proxying could take place and it works fine but I will need to change a library class in this way and I don't want to.
So here is the BeanSerializer.serialize method after my change:
@Override
public final void serialize(Object bean, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonGenerationException
{
bean = Util.deproxy(bean); // ***** Deproxy the bean here *****
jgen.writeStartObject();
if (_propertyFilterId != null) {
serializeFieldsFiltered(bean, jgen, provider);
} else {
serializeFields(bean, jgen, provider);
}
jgen.writeEndObject();
}
My question is how to do this without changing a library class(BeanSerializer)? I don't like this kind of hacks if there is a proper way.
回答1:
I've tried to do this particularly with Collections. So I've added new serializer for hibernate's PersistenceBag into mine ObjectMapper:
simpleModule.addSerializer(PersistentBag.class, new JsonSerializer<PersistentBag>() {
@Override
public void serialize(final PersistentBag collection, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider) throws IOException {
if(collection.wasInitialized()){
final Iterator iterator = collection.iterator();
//this is done to prevent Infinite Recursion, cause if we write PersistenceBag it will be serialized again.
jsonGenerator.writeObject(Iterators.toArray(iterator,Object.class));
}else{
//this is done to prevent NPE and undefined reference. (collections should be empty, but not null)
jsonGenerator.writeStartArray();
jsonGenerator.writeEndArray();
}
}
});
objectMapper.registerModule(simpleModule);
This prevents LazyInitializationException. If collections is not initialized it is written as empty array, otherwise it is just serialized.
(Iterators is from Google Guava lib)
来源:https://stackoverflow.com/questions/10627006/jersey-jax-rs-hibernate-and-lazyinitializationexception