【问题标题】:hibernate deproxy休眠代理
【发布时间】:2013-03-01 13:28:33
【问题描述】:

我正在使用休眠来实现持久性。在我的数据访问层中,我根据场景指定了结果的某些部分以立即加载。

现在我需要将这些结果作为 JAX WS 响应发送。

有没有什么方法可以让我有一些更简洁的方法来获取一个实体对象,遍历它,并将null设置为未初始化的字段,这样hibernate就不会在传递对象时抛出LazyInitializationException到网络服务层。

或者有没有其他方法可以解决这个问题。

【问题讨论】:

  • 你见过this吗?

标签: java hibernate


【解决方案1】:

有诸如Hibernate#initialize() 之类的东西,您可以在加载实体后在活动会话中运行它,但它会在您已传递的实体(或集合)的根级别初始化字段/引用——如果实体是休眠代理。正如 JavaDoc 所述:

注意:这只能确保代理对象或集合的初始化; 不能保证集合内的元素将是 初始化/物化。

将 NULL 分配给未初始化的字段不是一个好方法,因为它会破坏数据的一致性(如果有人访问这些字段,那么他们应该返回实际值)。

【讨论】:

    【解决方案2】:

    我在这里有相同的架构,我们在业务层执行加载工作。无法自动执行此操作,因为您只知道 ws 响应中需要哪些数据。基本上,我有一个方法可以将实体模型(JPA 映射)转换为简单的 POJO,反之亦然,在这个方法中我解决了需要加载哪个属性。

    你可以这样使用:

    public interface IBusiness<Model, VO> {
    
        public Model toModel(VO vo);
        public VO toVO(Model model);
        public List<Model> toModelList(List<VO> vos);
        public List<VO> toVOList(List<Model> models);
    
    }
    

    您在业务层上实现此接口并解决在此方法中加载您需要的所有内容的延迟问题。

    祝你好运=)

    【讨论】:

    • 是的,正如你所说,我解决了应该在我的数据访问层中加载哪些属性。我想知道是否有任何方法可以在通过 Web 服务发送之前自动“取消”未初始化的字段。
    • 我喜欢你的方法顺便说一句,你如何处理这样的场景:在一种情况下,你初始化了某个字段子集,而在另一种情况下,初始化了其他一些字段子集。跨度>
    • 您可以使用 Hibernate.initialize() 来加载未初始化的字段。但请注意......您必须使用未初始化的字段而不是对象实例来调用此方法。
    【解决方案3】:

    如果您使用的是 Spring,您可以使用 OpenSessionInView(Interceptor|Filter)。这是延迟初始化异常的简单修复,因为它将会话边界与请求边界对齐。我通常不喜欢这种方法,因为它通过对数据库执行额外查询来获取代理数据来消除错误。

    在像您这样的情况下,我的偏好是使用具有您对每次调用感兴趣的特定字段的传输对象。来回发送不必要的数据是没有意义的,或者更糟糕的是,发送歪曲持久层实际状态的数据。

    我实际上会更进一步,让您的会话边界保持原样,并确保您的 DAO 方法返回的是传输对象而不是实体。人们经常会争辩说实体只是 POJO,这只是更多的工作。但现实情况是,正如您的问题所示,将实体视为 POJO 的尝试可能会导致隐式数据访问,该访问属于专用于数据访问的层。

    【讨论】:

    • 我不使用 spring,“人们经常会争辩说实体只是 POJO,这只是更多的工作”这正是我最初没有考虑 DTO 的原因。但正如您所指出的,在这里使用 DTO 将是一个很好的解决方案。你能给我指出任何设计模式/优雅的方式来处理实体的转换-> DTO
    • 我不确定 OpenSessionInView 过滤器是否能在这种情况下工作。
    • 当您考虑实体嵌套、集合和类型转换时,这是一个难以解决的问题(DTO 中的关系通常由原始 PK 字段而不是完整实体表示)。也许像 Dozer (dozer.sourceforge.net) 这样的东西会帮助你顺利到达那里。
    【解决方案4】:

    替代方案可能根本不使用延迟初始化。

    如何做取决于您处理的案例。您将在 SO 上找到答案。

    【讨论】:

    • 不使用延迟加载不是一种选择。如果所有关系都被急切地加载,我最终会得到大量不必要的数据,当通过网络传输时,这将是一个重大的性能问题。
    • 因此,我建议您在周期结束前“自行”解决必要数据的加载。 =)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-25
    • 1970-01-01
    • 2023-03-29
    相关资源
    最近更新 更多