【问题标题】:Retaining EntityManager Session during JAX-RS serialization在 JAX-RS 序列化期间保留 EntityManager 会话
【发布时间】:2014-10-22 15:35:50
【问题描述】:

我有一个简单的 JAX-RS 资源,用于序列化 JPA 实体的视图。 JAX-RS 资源从 DAO 获取实体,将其传递给 bean 映射器,然后序列化结果。你会认为这很容易实现。

不。在尝试转换时,我得到一个 LazyInitializationException。我显然丢失了 EntityManager 会话。

我有一个解决方法,我将从 JAX-RS 资源而不是 DAO 输入事务,以保留相同的 EntityManager,但这在我的嘴里留下了不好的味道。

使用 CDI、JPA 和 JAX-RS,一旦我离开由 DAO 启动的事务,我将如何保留我的 EntityManager 的会话?

【问题讨论】:

    标签: java jpa jax-rs cdi


    【解决方案1】:

    DAO 的目标是封装和抽象对数据层的访问。因此,DAO 应该准确地提供消费者需要的数据。

    由于您的 fetchType 是惰性的,因此您的 DAO 仅提供部分数据,其中包含可以从数据库中获取更多数据的信息。在没有活动会话的情况下,获取数据失败。

    你有两个选择:

    1. 当您尝试从 JAX-RS 资源输入事务时,但这会使您的 DAO 变得荒谬。在这种情况下,我只需删除 DAO 并将 EntityManager 注入 JAX-RS 资源中。
    2. 按预期使用您的 DAO,并初始化消费者期望的所有数据。这可以通过Hibernate.initialize(entity) 或一些辅助方法来完成,该方法迭代丢失的实体并简单地在每个实体上调用entity.getId()

    【讨论】:

    • 此时我的DAO的功能主要是封装一些搜索逻辑:按名称查找,包含X的集合。我应该将这些简化为辅助方法吗?
    • 一个 DAO 是否有意义取决于很多事情——尤其是你想信奉哪种宗教。如果您的 DAO 也被其他服务使用,我会添加一些初始化更多数据的方法。
    【解决方案2】:

    我的意见是你的 DAO 应该返回一个已经初始化所有需要的关系的实体。 JAX-RS Resource 的作用应该只是序列化你给它的任何东西,它不应该担心惰性关系。

    【讨论】:

    • 其他服务需要使用同一个DAO,如果不需要数据,每次都急于加载是浪费。
    • 将惰性集合标记为渴望是一种浪费,但是您可以为不同的目的使用不同的 DAO 方法,即使它们基本上做同样的事情。在类似的情况下,我们的服务方法(除了基本参数,例如id,如果您通过 id 查询对象)也接受了一个配置对象,该对象包含有关需要初始化哪些关系的信息。这样您就可以在各种场景中使用相同的方法,而不会产生开销。
    • 如果您广泛使用 JsonView,那么根据您的视图初始化每个惰性属性将是地狱。 JsonView 的全部优点在于它返回属性的子集,如果该属性延迟初始化,那么您将自动优化您的数据库查询。 Cilph 问题非常有效。
    猜你喜欢
    • 2011-07-22
    • 2015-02-16
    • 1970-01-01
    • 2017-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-20
    • 1970-01-01
    相关资源
    最近更新 更多