Jersey JAX-RS,Hibernate和LazyInitializationException [英] Jersey JAX-RS, Hibernate and LazyInitializationException
问题描述
我正在研究Java EE 6.0 RESTful应用程序,并使用Hibernate。我需要在序列化之前取消代理我的惰性加载对象(实际上是实体的惰性加载的实体属性)以避免LazyInitializationException。我已经在AMF服务中成功完成了这一任务,编写了一些实用程序,在序列化实体之前做了这些工作。
我正在使用Jersey JAX-RS实现,我需要做这与杰克逊。我在BeanSerializer中发现了一个地方,我相信代理可以发生并且工作正常,但是我需要以这种方式更改一个库类,而且我不想。
所以这里是我更改后的BeanSerializer.serialize方法:
@Override
public final void serialize(Object bean,JsonGenerator jgen,SerializerProvider提供者)
抛出IOException,JsonGenerationException
{
bean = Util.deproxy(bean); // *****在这里deproxy这个bean *****
jgen.writeStartObject();
if(_propertyFilterId!= null){
serializeFieldsFiltered(bean,jgen,provider);
} else {
serializeFields(bean,jgen,provider);
}
jgen.writeEndObject();
我的问题是如何在不更改库类的情况下执行此操作BeanSerializer)?如果有正确的方法,我不喜欢这种黑客攻击。
我试图特别用集合来做到这一点。因此,我为hibernate的 PersistenceBag 添加了新的序列化程序到我的 ObjectMapper 中:
simpleModule.addSerializer(PersistentBag.class,new JsonSerializer< PersistentBag>(){
@Override $ b $ public void serialize(final PersistentBag集合,final JsonGenerator jsonGenerator,final SerializerProvider serializerProvider)throws IOException {
if(collection.wasInitialized()){
final Iterator iterator = collection.iterator();
//这样做是为了防止无限递归,因为如果我们编写PersistenceBag,它会被再次序列化。 b $ b jsonGenerator.writeObject(Iterators.toArray(iterator,Object.class));
} else {
//这样做是为了防止NPE和未定义的引用(集合应该是空的,但不能null)
jsonGenerator.writeStartArray();
jsonGenerator.writeEndArray();
}
}
});
objectMapper.registerModule(simpleModule);
这可以防止 LazyInitializationException 。如果集合未初始化,则它被写为空数组,否则它就是序列化的。
(迭代器来自Google Guava lib)
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.
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)
这篇关于Jersey JAX-RS,Hibernate和LazyInitializationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!