【问题标题】:remove Hibernate from entity pojo's?从实体 pojo 中删除休眠?
【发布时间】:2011-12-16 07:01:15
【问题描述】:

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

我希望您的 cmets 了解此代码的缺点。例如。它不会从中删除“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);
        }                       
    }
}

【问题讨论】:

    标签: hibernate serialization pojo


    【解决方案1】:

    对象克隆可能吗?克隆您想要序列化并通过网络发送的每个对象。你必须编写一个克隆方法,尽管你不会为每个 POJO 都有一个额外的 DTO 类

    【讨论】:

      【解决方案2】:

      我不明白这一点。如果我理解正确

      • 远程客户端仍然必须在其类路径中包含 Hibernate jar,
      • 所有这些都是递归地初始化实体的所有 toOne 关联

      因此,由于集合中的代理未初始化,您可能仍会遇到延迟加载异常。您可能会向远程客户端传输比必要更多的数据,这可能不需要所有 toOne 关联和初始化所有集合。这样做当然会对数据库产生大量额外的查询。

      我的观点是

      • 客户端与服务器紧密耦合,可能依赖于 Hibernate,并使用分离的 Hibernate 实体。而且你应该只初始化客户端需要初始化的东西
      • 或者客户端 ios 松耦合,可能不依赖 Hibernate,然后您应该转移常见的 DTO,并将您的实体转换为 DTO。

      【讨论】:

      • 好吧,关键是我需要序列化 ​​Hibernate pojo 对象的整个图形,以便将其发送到远程机器。那台机器没有任何 Hibernate jar,因此我需要从该对象图中删除所有 Hibernate 痕迹。我展示的代码是一种尝试,但它并不完整,因为它不会删除诸如持久集之类的东西。那么如何改进这段代码呢?
      • 正如我所说,我认为在 99% 的情况下,客户端不需要整个图表。具有双向关联的递归对象的整个图可以使您加载一半的数据库。我会让客户端定义一个包含它真正需要的 DTO,并从实体填充这个 DTO。
      • 但是 DTO 不是反模式吗?另外,如果对象和它们的关联很小,那么让它们去休眠然后发送它们不是很合理吗?
      • DTO 是一种反模式,用于在单个应用程序的两个部分之间传输可以作为实体发送的信息。您似乎有两个不同的松散耦合应用程序。 DTO 对我来说很合适。如果实体很小,将它们转换为 DTO 会更容易。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-22
      • 1970-01-01
      • 1970-01-01
      • 2011-10-18
      相关资源
      最近更新 更多