Hibernate实体中的CDI注入

问题描述 投票:3回答:3

我们在我们的应用程序中使用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
3个回答
3
投票

我真的不知道CDI,但我真的不认为这是可能的。事件,如果我们可以,在许多情况下,它可能会导致一个非常糟糕的设计。

你希望CDI为整个应用程序创建一个单独的hibernate实体,并注入你的帮助者/服务/其中的任何内容吗?或者您希望CDI在您使用“new Entity()”创建的任何实体中注入内容吗?


编辑:通常日期时间工具不保持任何状态,并且不需要任何CDI注入的东西,那么为什么不使所有方法静态像我们在apache commons DateUtils中找到的那样?

如果您的Date Time utils需要一个状态,请将其设为单例(但要注意并发问题)。

如果你的Date Time utils需要调用其他CDI bean(因此它不能是静态的)那么你宁愿把它变成一个单例,并在单例上注入其他CDI bean。

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


2
投票

将JPA实体系统地用作CDI bean是一种不好的做法(但如果你愿意的话,这是可能的)。这主要是因为CDI的'C':上下文。

所有CDI实现都使用代理机制来处理不同范围的bean中给定范围的bean的注入。并且由于大多数JPA实现也使用代理来处理某种机制(例如Lazy Loading),您将在类中使用不同生命周期的一堆代理完成:一团糟!

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

但是,在某些情况下,将实体公开为CDI bean可能很有用,但您更喜欢使用生产者来执行此操作:

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

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


0
投票

您可以在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()

© www.soinside.com 2019 - 2024. All rights reserved.