我的问题与此问题非常相似:Injecting fields via Spring into entities loaded by Hibernate
不同之处在于,我使用的是JPA2实体,而不是hibernate。虽然底层仍然处于休眠状态(3.5.5)。
我的春季版本是3.0.4。
JPA世界中相应的eventListeners
是什么?
原帖中的示例代码:
class Student {
int id; //loaded from DB
String name; //loaded from DB
int injectedProperty; //Inject via Spring
transient Service serviceImpl; //Inject via Spring
}
我知道可能有aspectJ的解决方案,但我更喜欢纯java解决方案。 感谢。
答案 0 :(得分:8)
JPA世界中相应的eventListeners是什么?
JPA有实体监听器(和回调方法)。从JPA 2.0规范:
3.5实体监听器和回调方法
可以将方法指定为a 生命周期回调方法接收 实体生命周期的通知 事件。生命周期回调方法 可以在实体类上定义,a 映射的超类或实体 与一个关联的监听器类 实体或映射的超类。一个实体 listener类是一个类 调用方法以响应 实体上的生命周期事件。任何 实体监听器类的数量可以 为实体类定义或 映射的超类。
(...)
实体监听器类必须具有 public no-arg constructor。
实体监听器是无状态的。该 实体监听器的生命周期是 未指定的。
以下规则适用于生命周期 回调:
- 生命周期回调方法可能会抛出未经检查/运行时异常。一个 回调抛出的运行时异常 在a中执行的方法 事务导致该事务 标记为回滚。
- 生命周期回调可以调用JNDI,JDBC,JMS和企业bean。
- 通常,便携式应用程序的生命周期方法不应该 调用EntityManger或Query 操作,访问其他实体 实例,或修改关系 在相同的持久化上下文中。一个 生命周期回调方法可能会修改 非关系状态 调用它的实体。
(...)
3.5.1生命周期回调方法
实体生命周期回调方法可以 在实体监听器类上定义 和/或直接在实体类或 映射的超类。
生命周期回调方法是 用注释指定注释 它们所属的回调事件 调用或映射到回调 使用XML描述符的事件。
用于回调的注释 实体类或映射的方法 超类和回调方法 实体监听器类是 相同。个人的签名 但是,方法不同。
在实体上定义的回调方法 class或映射的超类都有 签名如下:
void <METHOD>()
在实体上定义的回调方法 监听器类有以下内容 签名:
void <METHOD>(Object)
Object
参数是实体 回调方法的实例 被调用。它可能被宣布为 实际实体类型。回调方法可以具有公共,私有,受保护或包级访问权限,但不能是
static
或final
。(...)
以下是一个示例(来自规范):
@Entity
@EntityListeners(com.acme.AlertMonitor.class)
public class Account {
Long accountId;
Integer balance;
boolean preferred;
@Id
public Long getAccountId() { ... }
...
public Integer getBalance() { ... }
...
@Transient // because status depends upon non-persistent context
public boolean isPreferred() { ... }
...
public void deposit(Integer amount) { ... }
public Integer withdraw(Integer amount) throws NSFException {... }
@PrePersist
protected void validateCreate() {
if (getBalance() < MIN_REQUIRED_BALANCE)
throw new AccountException("Insufficient balance to open an account");
}
@PostLoad
protected void adjustPreferredStatus() {
preferred = (getBalance() >= AccountManager.getPreferredStatusLevel());
}
}
public class AlertMonitor {
@PostPersist
public void newAccountAlert(Account acct) {
Alerts.sendMarketingInfo(acct.getAccountId(), acct.getBalance());
}
}
在您的情况下,您可能需要PostLoad
回调方法。
另请参阅Hibernate Entity Manager文档中的Chapter 6. Entity listeners and Callback methods。
但简单来说,你想要做的就是使用JPA并不是那么简单,使用带有@Configurable
注释的AspectJ类编织可能是最好的选择。