【问题标题】:Get HibernateProxy at one object在一个对象上获取 HibernateProxy
【发布时间】:2019-04-17 07:36:30
【问题描述】:

我在 Spring Boot API 工作。这是我第一次遇到这个问题。

我通过存储库的 findById 函数加载不同的公司对象。所有公司对象都正确加载,期待一个。这个加载一个 JavassistLazyInitalizer 类型的处理程序属性。其余属性均按默认值。在目标节点的处理程序对象中,是我想要的正确加载的对象。

所以我发现这是一种hibernate延迟加载,因为当我想用getter访问一个属性时,它可以正常工作。

我的问题是,我想在最后用 gson 序列化对象,但在序列化过程中出现此错误:

尝试序列化 java.lang.Class:org.hibernate.proxy.HibernateProxy。忘记注册类型适配器?

我明白为什么会出现这个错误。但我不明白为什么只有一个不同的公司对象是延迟加载的(或者是 hibernateProxy)。 那么避免hibernateProxy分别序列化对象的最聪明的方法是什么?

感谢您的回答:)

【问题讨论】:

  • 序列化实体不是最好的主意。特别是如果他们彼此之间有关系 - 你可能会陷入递归陷阱
  • 他们之间没有关系,但感谢您的提示:)

标签: java mysql hibernate spring-boot proxy


【解决方案1】:

原因可能是您对正确加载的对象进行了一些操作。例如,如果您调用已加载持久类的任何方法(不是必需的 getter),Hibernate 会初始化所有代理。

而且你对加载不正确的对象什么也不做。

【讨论】:

    【解决方案2】:

    这个适配器是我的解决方案。

    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。

    new GsonBuilder().registerTypeAdapterFactory(HibernateProxyTypeAdapter.FACTORY).create();
    

    在这个问题上找到答案Could not serialize object cause of HibernateProxy

    【讨论】:

      猜你喜欢
      • 2019-10-25
      • 2011-08-26
      • 1970-01-01
      • 1970-01-01
      • 2019-12-22
      • 2021-11-09
      • 2012-11-07
      • 2019-01-30
      • 2011-09-08
      相关资源
      最近更新 更多