Hibernate 实体中的 CDI 注入
我们在应用程序中使用 CDI(JSR 299) (JSF2/Seam3.0/Hibernate 3.5.6/GlassFish 3.1.1)
虽然我们无法使用 @Inject 在托管 bean 中注入资源(Helper POJO),但我们不能这样做我们的 Hibernate 实体类中也是如此。
我们有一个所有实体对象派生自的基实体类(@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 实体。
任何意见将不胜感激。
谢谢&问候
We are using CDI(JSR 299) in our application (JSF2/Seam3.0/Hibernate 3.5.6/GlassFish 3.1.1)
While we are unable to inject resources(Helper POJOs) in our managed beans using @Inject, we cannot do the same in our Hibernate Entity classes.
We have a base entity class(@MappedSuperclass) that all entity objects derive from. CDI injection fails in both classes.
@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
}
It seems like it may be a limitation with CDI. Can anyone confirm whether CDI works with Hibernate entities.
Any inputs would be appreciated.
Thanks & Regards
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我不太了解 CDI,但我真的不认为这是可能的。
如果我们可以的话,在很多情况下,它可能会导致非常糟糕的设计。
您是否希望 CDI 为整个应用程序创建单个休眠实体,并在其中注入您的帮助程序/服务/其他内容?
或者您是否希望 CDI 在您使用“new Entity()”创建的任何实体中注入内容?
编辑:
一般来说,日期时间 utils 不保存任何状态,也不需要任何 CDI 注入的东西,那么为什么不像我们在 apache commons DateUtils 中找到的那样将所有方法设为静态呢?
如果您的日期时间实用程序需要一个状态,请将其设为单例(但要注意并发问题)。
如果您的日期时间实用程序需要调用其他 CDI bean(因此它不能是静态的),那么您宁愿将其设为单例,并在单例上注入其他 CDI bean。
但这是一个坏主意。
这可能会导致业务层管理回调业务层的实体或类似的东西,并存在一些循环依赖问题以及实体和业务层之间的紧密耦合。
I don't really know CDI but i really don't think it is possible.
Event if we could, in many cases, it would probably lead to a really bad design.
Do you wish CDI to create a single hibernate entity for the whole application, and inject your helpers/services/whatever in it?
Or do you wish CDI to inject stuff in any entity you create with "new Entity()"?
Edit:
Generally a Date Time utils doesn't hold any state and doesn't need any CDI injected stuff, so why not make all the methods static like what we find in apache commons DateUtils?
If your Date Time utils need a state, make it a singleton (but take care with concurrency issues).
If your Date Time utils needs to call other CDI beans (so it can't be static) then you'd rather make it a singleton, and inject on the singleton the other CDI beans.
But it's a bad idea.
This may lead to have a business layer that manage entities that call back the business layer or something like that, with some circular dependency problems and a tight coupling between your entities and your business layer.
系统地使用 JPA 实体作为 CDI bean 是一种不好的做法(但如果您愿意,这是可能的)。这主要是因为 CDI 的“C”:上下文。
所有 CDI 实现都使用代理机制来处理给定范围的 bean 到不同范围的 bean 中的注入。由于大多数 JPA 实现还使用代理来处理某些机制(例如延迟加载),您将在类中使用一堆具有不同生命周期的代理:一团糟!
Weld 文档甚至对这个问题有所减弱:第 5 章。范围和上下文
然而,在某些情况下将实体公开为 CDI bean 可能很有用,但您更喜欢使用生产者来执行此操作:
这种方式是最方便的,但您应该这样做混合托管实体和 CDI 时要非常小心
It's a bad practice to systematically use JPA entity as CDI bean (but it's possible if you want to). That's mainly because of the 'C' of CDI : Context.
All CDI implementations use proxy mechanism to handle injection of a bean of a given scope in a bean of a different scope. And as most JPA implementation use also proxy to handle some mechanism (Lazy Loading for instance) you will finished with a bunch of proxies in your class with different life cycles : a mess !
Weld documentation as even a waning about this issue : Chapter 5. Scopes and Contexts
However it could be useful in some case to expose an entity as CDI bean, but you'd prefer to use a producer to do so :
This way is the most convenient but you should be very careful when mixing managed entities and CDI
您可以在 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()
you can firing CDI Events in a JPA Entity or EntityListener. and inject the TestClass to the class which contains Observes method.
look at following link for more information:
http://blogs.bytecode.com.au/glen/2014/01/09/firing-cdi-events-from-a-jpa-entitylistener.html
you can also access to the BeanManager as follow( instead JNDI lookup)
CDI.Current().getBeanManager()