`
hapinwater
  • 浏览: 70860 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Hessian序列化Hibernate的延迟加载Set等集合的解决方案

阅读更多
假如有如下类,Customer和Order,在使用Hessian序列化Customer时,如果orders延迟加载,并且序列化时Hibernate的session已经关闭,则会抛出Hibernate的LazyInitializationException.

@Entity
public class Customer implements java.io.Serializable {

    @Id
    private long id;

    
    private String name;

    //一对多,延迟加载
    @OneToMany(fetch=FetchType.LAZY)
    @JoinColumn(name="CUSTOMER_ID")
    private Set<Order> orders;
    ...........


@Entity
public class Order implements java.io.Serializable{

    @Id
    private long id;

    .......




该Set为Hibernate的PersistentSet,是Hibernate的PersistentCollection的子类。原因是Hessian序列化时,会调用PersistentSet的方法导致Hibernate从session里加载数据,如果session已经关闭,就会抛出异常,导致序列化出错。不仅Set会出现,PersistentCollection的其他子类也会出现该现象,如PersistentList,PersistentBag,PersistentMap等。使用JDK的序列化不会出现该现象。

解决方案如下,可以为Hibernate的PersistentColletion定制一个Serializer,代码如下:
import com.caucho.hessian.io.AbstractHessianOutput;
import com.caucho.hessian.io.AbstractSerializer;
import com.caucho.hessian.io.CollectionSerializer;
import com.caucho.hessian.io.MapSerializer;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import org.hibernate.Hibernate;
import org.hibernate.collection.PersistentMap;


public class HibernateSerializer extends AbstractSerializer {

    CollectionSerializer collectionSeiralizer = new CollectionSerializer();
    
    MapSerializer mapSerializer = new MapSerializer();

    @Override
    public void writeObject(Object obj, AbstractHessianOutput out) throws IOException {

        boolean init = Hibernate.isInitialized(obj);

        if (init) {
            out.writeObject(obj);
            out.flush();
            return;
        }

        if (PersistentMap.class.isAssignableFrom(obj.getClass())) {
            //将没有初始化的Map序列化空的HashMap
            mapSerializer.writeObject(new HashMap(), out);
        } else {
            //将没有初始化的List,Set等序列化为空的ArrayList
            collectionSeiralizer.writeObject(new ArrayList(), out);
        }
    }

    

}


同时还需要定制一个序列化工厂SerializerFactory,代码如下:
import com.caucho.hessian.io.HessianProtocolException;
import com.caucho.hessian.io.Serializer;
import com.caucho.hessian.io.SerializerFactory;
import org.hibernate.collection.PersistentCollection;


public class HibernateSerializerFactory  extends SerializerFactory {

    @Override
    public Serializer getSerializer(Class cl) throws HessianProtocolException {

        //Hibernate的集合API使用为HibernateSerializer序列化
        if (PersistentCollection.class.isAssignableFrom(cl)) {
            return new HibernateSerializer();
        }
        return super.getSerializer(cl);
    }

}


可以调用HessianServlet.getSerializerFactory().addFactory()添加HibernateSerializerFactory  来使用该HibernateSerializer序列化Hibernate的PersistentCollection.
或者写一个serializers文件放到classpath的META-INF/hessian/目录下,该文件的内容为
org.hibernate.collection.PersistentCollection=HibernateSerializer
分享到:
评论
3 楼 finny2009 2015-01-14  
hessian和spring集合了 没有用到hessianServlet怎么使用addFactory()那
2 楼 hapinwater 2012-01-20  
Hessian的通常需要继承HessianServlet,然后在Servlet的init方法里调用HessianServlet.getSerializerFactory().addFactory(),把这个HibernateSerializerFactory加进去就可以。
1 楼 zhoujianghua 2011-10-09  
“可以调用HessianServlet.getSerializerFactory().addFactory()添加 HibernateSerializerFactory  来使用该HibernateSerializer序列化Hibernate的PersistentCollection.
或者写一个serializers文件放到classpath的META-INF/hessian/目录下,该文件的内容为”

是怎么做啊?看不大懂。。。。

相关推荐

    第二期2020字节跳动面试题及解析.pdf

    默认使用Netty作为网络通信框架,Hessian2作为序列化框架,支持多种其他通信和序列化框架,如mina、http等。 #### 4.4 Dubbo服务注册与发现的流程 服务提供者启动时,会向注册中心注册自己的地址信息。服务消费者...

    1000道 互联网Java工程师面试题 485页 .pdf

    Dubbo默认使用Hessian序列化框架,同时也支持如JSON、Java自带序列化等其他序列化框架。 #### 服务提供者失效踢出和服务上线 Dubbo服务提供者失效踢出通过心跳检测机制实现。服务上线不影响旧版本,可以通过版本...

    1000道互联网Java工程师面试题485页.pdf

    6. **默认序列化框架**:默认使用Hessian2序列化框架,也可以使用Java序列化、JSON序列化等。 7. **服务失效踢出原理**:服务提供者在一定时间内没有更新服务,则会被注册中心踢出。 8. **服务上线不影响旧版本**...

    1000道 互联网Java工程师面试题 485页_PDF密码解除.pdf

    - 默认使用Hessian,支持Java原生序列化、JSON等。 7. **服务失效踢出**: - 服务提供者下线时,自动踢出。 8. **服务版本管理**: - 避免新旧版本冲突。 9. **服务调用链优化**: - 如通过合并请求、优化协议等...

    1000道 互联网Java工程师面试题 485页

    #### 22、Mybatis是否支持延迟加载?如果支持,它的实现原理是什么? - **支持情况**:MyBatis支持懒加载。 - **实现原理**:通过代理对象在实际需要时才触发查询。 #### 23、Mybatis的一级、二级缓存: - **一级...

Global site tag (gtag.js) - Google Analytics