【问题标题】:CDI Injection in Hibernate EntitiesHibernate 实体中的 CDI 注入
【发布时间】:2011-12-14 22:28:46
【问题描述】:

我们在我们的应用程序中使用 CDI(JSR 299) (JSF2/Seam3.0/Hibernate 3.5.6/GlassFish 3.1.1)

虽然我们无法使用 @Inject 在托管 bean 中注入资源(Helper POJO),但我们无法在 Hibernate Entity 类中执行相同操作。

我们有一个基础实体类(@MappedSuperclass),所有实体对象都从它派生。 CDI 注入在两个类中都失败。

@MappedSuperclass
public class BaseBusinessObject implements Serializable
{     
    @Inject
    private TestClass testClass; //FAILS
}


@Entity
@NamedQueries({ @NamedQuery(name = "Account.findAll", query = "SELECT b FROM Account b") })
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Account extends BaseBusinessObject
{
    @Inject
    private TestClass testClass; //FAILS

}

这似乎是 CDI 的限制。任何人都可以确认 CDI 是否适用于 Hibernate 实体。

任何意见将不胜感激。

感谢和问候

【问题讨论】:

    标签: hibernate jpa cdi entities


    【解决方案1】:

    我并不真正了解 CDI,但我真的不认为这是可能的。 如果可以的话,在很多情况下,它可能会导致一个非常糟糕的设计。

    您是否希望 CDI 为整个应用程序创建一个单一的休眠实体,并在其中注入您的助手/服务/任何东西? 还是您希望 CDI 在您使用“new Entity()”创建的任何实体中注入内容?


    编辑: 一般来说,日期时间实用程序不保存任何状态,也不需要任何 CDI 注入的东西,那么为什么不像我们在 apache commons DateUtils 中找到的那样将所有方法设为静态?

    如果您的日期时间工具需要状态,请将其设为单例(但要注意并发问题)。

    如果您的日期时间实用程序需要调用其他 CDI bean(因此它不能是静态的),那么您宁愿将其设为单例,并在该单例上注入其他 CDI bean。

    但这是个坏主意。 这可能会导致有一个业务层来管理回调业务层的实体或类似的东西,存在一些循环依赖问题以及实体和业务层之间的紧密耦合。

    【讨论】:

    • 嗨塞巴斯蒂安,感谢您的回复。我们使用多个 Hibernate 实体,但它们都从一个基本实体类派生(基本属性,如创建日期时间)。我们试图在这个基类中注入一个日期时间实用程序类来获取实体创建时间,这个注入失败了。
    【解决方案2】:

    系统地将 JPA 实体用作 CDI bean 是一种不好的做法(但如果您愿意,也可以这样做)。这主要是因为 CDI 的“C”:上下文。

    所有 CDI 实现都使用代理机制来处理将给定范围的 bean 注入到不同范围的 bean 中。而且由于大多数 JPA 实现还使用代理来处理某些机制(例如延迟加载),您将在您的类中完成一堆具有不同生命周期的代理:一团糟!

    焊接文档甚至对这个问题有所减弱:Chapter 5. Scopes and Contexts

    但是,在某些情况下,将实体公开为 CDI bean 可能很有用,但您更愿意使用生产者来这样做:

    @Produces
    @Named
    @RequestScoped
    private MyEntity produceMyEntity()
    {
         return new MyEntity(); //or any JPA lookup you'll need
    }
    

    这种方式最方便,但在混合托管实体和 CDI 时应该非常小心

    【讨论】:

    • 您好 Antoine,感谢您的回复。我们不尝试使用 CDI 生成实体。该实体是使用 new() 运算符生成的。但是,正如 Sebastien 所指定的,我们所有的实体(基本属性,如创建日期时间)都是从一个基本实体类派生的。我们试图在这个基类中注入一个日期时间实用程序类来获取实体创建时间,这个注入点失败了。如果您需要更多信息,请告诉我。
    【解决方案3】:

    您可以在 JPA 实体或 EntityListener 中触发 CDI 事件。并将 TestClass 注入到包含 Observes 方法的类中。 查看以下链接以获取更多信息: http://blogs.bytecode.com.au/glen/2014/01/09/firing-cdi-events-from-a-jpa-entitylistener.html

    您也可以按如下方式访问 BeanManager(而不是 JNDI 查找)

    CDI.Current().getBeanManager()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-20
      • 2014-12-13
      • 1970-01-01
      • 2013-10-13
      • 2016-03-24
      相关资源
      最近更新 更多