从实体pojo'中删除Hibernate;s

从实体pojo'中删除Hibernate;s,hibernate,serialization,pojo,Hibernate,Serialization,Pojo,我一直在尝试从实体pojo中删除Hibernate特定的细节(例如,当我需要序列化它们并发送到远程机器时),下面是我提出的代码。它的“initializeAndUnproxy()”取自Bozho给出的一个答案:我对它进行了修改,在其中调用了递归方法 我想听听你对这段代码的评论,看看它的缺点。例如,它不会从中删除“PersistentSet”类型。那么你有什么改进建议 static <T> T initializeAndUnproxy(T entity) throws IllegalA

我一直在尝试从实体pojo中删除Hibernate特定的细节(例如,当我需要序列化它们并发送到远程机器时),下面是我提出的代码。它的“initializeAndUnproxy()”取自Bozho给出的一个答案:我对它进行了修改,在其中调用了递归方法

我想听听你对这段代码的评论,看看它的缺点。例如,它不会从中删除“PersistentSet”类型。那么你有什么改进建议

static <T> T initializeAndUnproxy(T entity) throws IllegalArgumentException, IllegalAccessException
{
    if(entity == null)
    {         
        throw new NullPointerException("Entity passed for initialization is null");     
    } 

    Hibernate.initialize(entity);       
    T ret = entity;

    if(entity instanceof HibernateProxy)
    {           
        ret = (T)((HibernateProxy)entity).getHibernateLazyInitializer().getImplementation();
        initializeRecursively(ret);         
    }

    return ret;
}

static void initializeRecursively(Object entity) throws IllegalArgumentException, IllegalAccessException
{
    Class<?> clazz = entity.getClass();
    Field[] fields = clazz.getDeclaredFields();

    for(Field field : fields)
    {
        field.setAccessible(true);          
        Object obj = field.get(entity);                     
        Hibernate.initialize(obj);

        if(obj instanceof HibernateProxy)
        {                               
            obj = ((HibernateProxy)obj).getHibernateLazyInitializer().getImplementation();
            field.set(entity, obj);     
            initializeRecursively(obj);
        }           
        if(obj instanceof LazyInitializer)
        {                       
            obj = ((LazyInitializer)obj).getImplementation();   
            initializeRecursively(obj);
        }                       
    }
}
静态T initializeAndUnproxy(T实体)抛出IllegalArgumentException、IllegalAccessException
{
if(实体==null)
{         
抛出新的NullPointerException(“为初始化传递的实体为null”);
} 
初始化(实体);
T ret=实体;
if(HibernateProxy的实体实例)
{           
ret=(T)((HibernateProxy)实体).getHibernateLazyInitializer().getImplementation();
草率初始化(ret);
}
返回ret;
}
静态void初始化递归(对象实体)抛出IllegalArgumentException、IllegalAccessException
{
Class clazz=entity.getClass();
Field[]fields=clazz.getDeclaredFields();
用于(字段:字段)
{
字段。setAccessible(true);
Object obj=field.get(实体);
Hibernate.initialize(obj);
if(HibernateProxy的obj实例)
{                               
obj=((HibernateProxy)obj.getHibernateLazyInitializer().getImplementation();
字段集(实体、对象);
草率初始化(obj);
}           
if(LazyInitializer的obj实例)
{                       
obj=((LazyInitializer)obj.getImplementation();
草率初始化(obj);
}                       
}
}

我看不出有什么意义。如果我理解正确的话

  • 远程客户端的类路径中仍然必须有Hibernate JAR
  • 所有这一切都是递归地初始化实体的所有toOne关联
因此,由于集合中未初始化的代理,您可能仍然会有延迟加载异常。您可能需要向远程客户端传输更多的数据,而远程客户端可能不需要初始化所有的toOne关联和所有集合。这样做当然会对数据库产生大量额外的查询

我的观点是

  • 客户机与服务器紧密耦合,可能依赖于Hibernate,并且使用分离的Hibernate实体。您应该只初始化客户端需要初始化的内容
  • 或者客户端ios松散耦合,可能不依赖于Hibernate,然后您应该传输公共DTO,并将您的实体转换为DTO

    • 对象克隆可能吗?克隆要序列化并通过网络发送的每个对象。您确实需要编写一个clone方法,尽管您不会为每个POJO都增加一个DTO类,但关键是我需要序列化Hibernate POJO对象的整个图形,以便将其发送到远程机器。这台机器不会有任何Hibernate JAR,因此我需要从对象图中删除Hibernate的所有痕迹。我展示的代码是一个尝试,但它并不完整,因为它没有删除持久集之类的东西。那么如何改进这段代码呢?正如我所说的,我认为在99%的情况下,客户机不需要整个图形。一个具有双向关联的递归对象图可以让您加载数据库的一半。我会让客户端定义一个包含它真正需要的DTO,并从实体中填充这个DTO。但DTO不是反模式吗?另外,如果对象及其关联很小,那么将它们解除休眠然后发送它们是否合理?当DTO用于在单个应用程序的两个部分之间传输可以作为实体发送的信息时,DTO是一种反模式。您似乎有两个不同的、松散耦合的应用程序。DTO在我看来很合适。如果实体很小,则更容易将其转换为DTO。