如何解决当一个 JPA/Hibernate 实体只有一个实体没有 EntityManager/Session时,如何锁定一个 JPA/Hibernate 实体?
我正在处理一些遗留代码,在某些地方,没有一种干净可靠的方法来获取给定实体的 JPA EntityManager(或 Hibernate Session),以便根据需要调用 lock(...) 方法.本质上,我们在实体中有一个方法需要执行以下操作:
@Entity
public class SomeEntity {
@Column(...)
@Basic(...)
private String name;
...
public void doSomething(/* arguments irrelevant */) {
...
myCurrentEntityManagerOrSession.lock(...);
...
}
...
}
问题是如何做到这一点 - 如何访问该实体管理器或会话?我们编造了两种方法来完成我们需要的事情,尽管这两种方法都有效,但都不理想:
选项 #1 - 令人尴尬的财产触发器
final String originalName = getName();
setName("modified " + originalName);
setName(originalName);
...“欺骗”Hibernate(我们使用字节码增强,顺便说一句)来执行锁定本身,然后撤消更改但保留锁定(我们会在任何“廉价”属性上执行此操作)。
选项 #2:不当滥用 Hibernate 字节码增强及其内部 API 的反射
private static final Method HIBERNATE_ENTITY_ENTRY_GETTER;
static {
Method getter;
try {
getter = SomeEntity.class.getmethod("$$_hibernate_getEntityEntry");
} catch (NoSuchMethodException e) {
/// Oooh .. not good!
getter = null;
}
HIBERNATE_ENTITY_ENTRY_GETTER = getter;
}
public Session getEntitySession() {
try {
final MutableEntityEntry entry = (MutableEntityEntry) HIBERNATE_ENTITY_ENTRY_GETTER.invoke(this);
return (Session) entry.getPersistenceContext().getSession();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void lock(final LockMode lockMode) {
getEntitySession().lock(this,lockMode);
}
public void lock() {
lock(LockMode.OPTIMISTIC_FORCE_INCREMENT);
}
是否有适当、干净的方法来获取当前管理/拥有特定实体的 EntityManager/Session?我们知道底层引擎必须已经知道这一点,当然......但似乎这很好地隐藏起来。
附加说明:ThreadLocal 在某些项目中可能是一种解决方案,但在本项目中则不然。别问了。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。