重点技术-20181008-GSON 报错HibernateProxy. Forgot to register a type adapter?

摘要: Attempted to serialize java.lang.Class: org.hibernate.proxy.HibernateProxy. Forgot to register a type adapter?

使用Gson转换Hibernate对象遇到一个问题,当对象的Lazy加载的,就会出现上面的错误。处理方式摘抄自网上,留存一份以后自己看。

 
  1. /**

  2. * This TypeAdapter unproxies Hibernate proxied objects, and serializes them

  3. * through the registered (or default) TypeAdapter of the base class.

  4. */

  5. public class HibernateProxyTypeAdapter extends TypeAdapter<HibernateProxy> {

  6.  
  7. public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {

  8. @Override

  9. @SuppressWarnings("unchecked")

  10. public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {

  11. return (HibernateProxy.class.isAssignableFrom(type.getRawType()) ? (TypeAdapter<T>) new HibernateProxyTypeAdapter(gson) : null);

  12. }

  13. };

  14. private final Gson context;

  15.  
  16. private HibernateProxyTypeAdapter(Gson context) {

  17. this.context = context;

  18. }

  19.  
  20. @Override

  21. public HibernateProxy read(JsonReader in) throws IOException {

  22. throw new UnsupportedOperationException("Not supported");

  23. }

  24.  
  25. @SuppressWarnings({"rawtypes", "unchecked"})

  26. @Override

  27. public void write(JsonWriter out, HibernateProxy value) throws IOException {

  28. if (value == null) {

  29. out.nullValue();

  30. return;

  31. }

  32. // Retrieve the original (not proxy) class

  33. Class<?> baseType = Hibernate.getClass(value);

  34. // Get the TypeAdapter of the original class, to delegate the serialization

  35. TypeAdapter delegate = context.getAdapter(TypeToken.get(baseType));

  36. // Get a filled instance of the original class

  37. Object unproxiedValue = ((HibernateProxy) value).getHibernateLazyInitializer()

  38. .getImplementation();

  39. // Serialize the value

  40. delegate.write(out, unproxiedValue);

  41. }

  42. }

实现上面的类,然后就是使用:

 
  1. GsonBuilder b = new GsonBuilder();

  2. ...

  3. b.registerTypeAdapterFactory(HibernateProxyTypeAdapter.FACTORY);

  4. ...

  5. Gson gson = b.create();

解释,只是看不懂。

GSON contains a number of TypeAdapterFactory implementations, for various types (primitive types, common types like String or Date, lists, arrays...). Each factory is asked if it is able to serialize a certain Java type (the parameter to create is a TypeToken instead of a Class in order to capture possible information about generic types, which Class does not have). If the factory is able to serialize/deserialize a type, it responds with a TypeAdapter instance; otherwise it responds with null.

HibernateProxyTypeAdapter.FACTORY verifies whether type implements HibernateProxy; in that case, it returns an instance of HibernateProxyTypeAdapter for serialization. The write method is called when an actual object has to be serialized; the adapter extracts the original type of the underlying object, and asks GSON for the standard TypeAdapter for the original type, which generally is a ReflectiveTypeAdapter.

Then it retrieves an instance of the original class, instead of directly using the proxy. This is necessary because ReflectiveTypeAdapter accesses directly to fields, instead of using getters; accessing to the fields of a proxied object does not work, and is a classical Hibernate pitfall.

As a possible performance improvement, the delegate TypeAdapter should be acquired in the create method. I found out that calling getSuperclass() on the proxy Class appears to yield the original base class.

--------------------- 本文来自 xspwz123 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/xspwz123/article/details/71425545?utm_source=copy

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值