栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

无法序列化HibernateProxy的对象原因

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

无法序列化HibernateProxy的对象原因

您可以通过使用custom无需手动取消代理所有内容

TypeAdapter
。遵循以下原则:

public class HibernateProxyTypeAdapter extends TypeAdapter<HibernateProxy> {    public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {        @Override        @SuppressWarnings("unchecked")        public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { return (HibernateProxy.class.isAssignableFrom(type.getRawType()) ? (TypeAdapter<T>) new HibernateProxyTypeAdapter(gson) : null);        }    };    private final Gson context;    private HibernateProxyTypeAdapter(Gson context) {        this.context = context;    }    @Override    public HibernateProxy read(JsonReader in) throws IOException {        throw new UnsupportedOperationException("Not supported");    }    @SuppressWarnings({"rawtypes", "unchecked"})    @Override    public void write(JsonWriter out, HibernateProxy value) throws IOException {        if (value == null) { out.nullValue(); return;        }        // Retrieve the original (not proxy) class        Class<?> baseType = Hibernate.getClass(value);        // Get the TypeAdapter of the original class, to delegate the serialization        TypeAdapter delegate = context.getAdapter(TypeToken.get(baseType));        // Get a filled instance of the original class        Object unproxiedValue = ((HibernateProxy) value).getHibernateLazyInitializer()     .getImplementation();        // Serialize the value        delegate.write(out, unproxiedValue);    }}

要使用它,您必须首先注册它:

GsonBuilder b = new GsonBuilder();...b.registerTypeAdapterFactory(HibernateProxyTypeAdapter.FACTORY);...Gson gson = b.create();

注意,这将递归地初始化对象层次结构中的每个代理。但是由于您必须序列化整个数据,因此无论如何都应该这样做。

这是如何运作的?

GSON包含许多

TypeAdapterFactory
针对各种类型(原始类型,常见类型(例如
String
或)
Date
,列表,数组等)的实现。询问每个工厂是否能够序列化某种Java类型(参数to
create
是a
TypeToken
而不是a
Class
,以便捕获有关泛型的可能信息,而
Class
没有泛型)。如果工厂能够序列化/反序列化类型,则它会以一个
TypeAdapter
实例进行响应;否则它会以回应
null


HibernateProxyTypeAdapter.FACTORY
验证 类型 是否实现
HibernateProxy
;
在这种情况下,它将返回一个实例
HibernateProxyTypeAdapter
进行序列化。
write
当必须对实际对象进行序列化时,将调用该方法。适配器提取基础对象的原始类型,并向GSON询问
TypeAdapter
原始类型的标准,通常为
ReflectiveTypeAdapter

然后,它检索原始类的实例,而不是直接使用代理。这是必要的,因为直接

ReflectiveTypeAdapter
访问字段,而不是使用getters。访问代理对象的字段无效,这是经典的Hibernate陷阱。

作为可能的性能改进,

TypeAdapter
应在
create
方法中获取委托。我发现调用
getSuperclass()
代理
Class
似乎产生了原始基类。代码可以变成:

public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {    @Override    @SuppressWarnings("unchecked")    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {        return (HibernateProxy.class.isAssignableFrom(type.getRawType())     ? (TypeAdapter<T>) new HibernateProxyTypeAdapter((TypeAdapter)gson.getAdapter(TypeToken.get(type.getRawType().getSuperclass())))      : null);    }};private final TypeAdapter<Object> delegate;private HibernateProxyTypeAdapter(TypeAdapter<Object> delegate) {    this.delegate = delegate;}@SuppressWarnings({"rawtypes", "unchecked"})@Overridepublic void write(JsonWriter out, HibernateProxy value) throws IOException {    if (value == null) {        out.nullValue();        return;    }    delegate.write(out, ((HibernateProxy) value).getHibernateLazyInitializer() .getImplementation());}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/435851.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号