【问题标题】:CDI Injecting services into JPA managed EntitiesCDI 将服务注入 JPA 托管实体
【发布时间】:2014-02-13 02:08:15
【问题描述】:

我确定这与this question 密切相关,但关于该问题的操作有一些场景,我甚至不确定是否对 DI 有意义。所以这就是我的理解,尝试将 JPA 实体与 CDI Bean 混合通常不是一个好主意,因为两者通常都是通过创建代理对象来完成的。这是我的设想,但根据我的阅读,这是不可能的。

@Entity
public class MyUniqueObject implements Serializable {

    @Inject
    private transient Logger log;

    @Inject
    private transient Event<MyUniqueObjectEvent> events;

    @Id
    private long id;

    @NotNull
    private String text;

    public void setText( final String text ) {
       log.debug( "updating text {}", this );
       this.text = text;
       events.fire( new MyUniqueObjectEvent( this ) ); // consumed by an @Observes method
    }
}

什么是最好的方法来做我想要完成的事情?这基本上是从 JPA 持久化实体中触发的事件、对日志对象的访问。代码示例很有帮助。

【问题讨论】:

  • 我可以看到您要执行的操作,但在我看来,您仍然在尝试将业务逻辑添加到实体 bean,因此在我看来这里有些问题。相反,我会将实体发送到某个业务逻辑类,该类可能会观察实体的变化。 (当然,您必须将 setText() 包装到业务对象中的其他内容),或者您可以使用某种 AOP 方式来拦截实体 bean 中的方法。不确定,只是一些想法。
  • @Leo 实体 bean 不允许有业务逻辑吗?我认为像 Hibernate 这样的东西的目的是能够直接持久化业务对象? Data Mapper
  • 好吧,我知道实体 bean 没有逻辑,它们只有数据,而 hibernate 只是处理它们的持久性。业务逻辑,另一方面,我知道有逻辑但(大多数时候)瞬态。但是,你知道,没有黄金法则。
  • 最后,我们只有一个问题、代码和开发人员;-)
  • 目前我唯一的想法是通过休眠加载实体,然后调用受保护的设置器来添加记录器/事件/等对象。

标签: java hibernate jpa cdi weld


【解决方案1】:

我想知道观察实体属性的每一个变化是否真的有用,即使它们最终不会被持久化。所以你不认为Entity Listeners and Callbacks 对你来说还不够吗?他们从 JPA 2.1 开始就支持 CDI 并提供了很多你可以观察到的回调

  • @PrePersist
  • @PreRemove
  • @PostPersist
  • @PostRemove
  • @PreUpdate
  • @PostUpdate
  • @PostLoad

所以你会得到

@EntityListeners(class=Audit.class)
@Entity
public class MyUniqueObject implements Serializable {}


public class Audit {

    @Inject
    private Logger log;

    @Inject
    private Event<MyUniqueObjectEvent> events;

}

现在您可以观察实体的生命周期 - 最好将模型与其审计分开,您不必为了实现日志记录而搞乱 setter 和 getter(这很令人困惑)。另请注意,您还可以为您拥有的每个实体定义Default Entity Listeners

【讨论】:

  • 当您不通过 JPA 持久化时是否可以使用它?例如我的一些测试。
  • 我不确定,但我认为回调将与 JPA 相关联,因此您不会在测试期间获得任何审计。但我不确定您为什么要这样做 - 通常您需要测试是否可以持久化实体,是否生成主键等等,测试 getter 或 setter 没有任何用途。
  • 因为我的示例被设计为过于简单,而不是提供我可能遇到的每一个案例......
  • 当然可以,但是就像我说的,将模型和逻辑结合起来并不是一个好主意,这两个东西应该简单地分开。
  • 为了未来的人,我决定写一个工厂,有一个factory create函数调用的方法,该方法也被@PostLoad注解,所以hibernate可以调用它。
猜你喜欢
  • 1970-01-01
  • 2011-06-11
  • 1970-01-01
  • 2012-04-12
  • 1970-01-01
  • 1970-01-01
  • 2013-02-20
  • 2015-08-06
  • 2011-11-18
相关资源
最近更新 更多