我通过覆盖 SimpleJpaRepository 为我的项目添加了一个监听器层,所以它看起来像这样:
@Override
@Transactional
public <S extends E> S save(S entity) {
if (entityInformation.isNew(entity)) {
persister.beforeCreateListenersFor(entity.getClass()).execute(entity);
entityManager.persist(entity);
persister.afterCreateListenersFor(entity.getClass()).execute(entity);
return entity;
} else {
S merged;
persister.beforeUpdateListenersFor(entity.getClass()).execute(entity);
merged = entityManager.merge(entity);
persister.afterUpdateListenersFor(entity.getClass()).execute(entity);
return merged;
}
}
@Override
public void delete(E entity) {
Assert.notNull(entity, "Entity must not be null.");
if (entity instanceof LogicRemovable) {
((LogicRemovable) entity).setLogicRemoved(true);
save(entity);
} else {
persister.beforeDeleteListenersFor(entity.getClass()).execute(entity);
entityManager.remove(entityManager.contains(entity) ? entity : entityManager.merge(entity));
persister.afterDeleteListenersFor(entity.getClass()).execute(entity);
}
}
其中 persister 是一个接口,它在运行时为给定类和给定类型(BEFORE_CREATE,AFTER_CREATE等)提供侦听器,并注入侦听器所需的所有内容。
一切都很有效,我所要做的就是用给定的注释注释听众。
问题是:由于此层位于存储库级别,因此不会影响级联实体。
那么,我怎样才能使它也影响级联实体呢?
对我来说,完美的解决方案是“只需将图层从存储库移动到X(就像实体管理器一样,不确定),它会影响两者”,但我不知道X是什么。
或许还有其他解决方案,欢迎任何解决方案。
谢谢!
-glauber
答案 0 :(得分:0)
你想和听众做什么?您使用的是实体监听器吗? https://docs.jboss.org/hibernate/entitymanager/3.5/reference/en/html/listeners.html。你能创建一个实体监听器并注释一个基础实体吗?
答案 1 :(得分:0)
我在这里回答了一个类似的问题。
Using Hibernate 4's Integrator pattern and Spring's dependency injection
有了这个,你可以使用spring bean作为hibernate监听器,它们是最低级别的。刷新的每个实体都将触发监听器。
这取决于你使用听众的内容。由于ActionQueue
已经构建,HibernateListeners不应该修改或创建新实体。 (但Envers
正在使用这些侦听器来创建修订历史记录。)
答案 2 :(得分:0)
非常感谢Martin Frey解决方案,我能够使用你的解决方案调整我的解决方案。
我所做的只是创建六个通用的Hibernate Listener,一个用于我正在使用的每个事件类型,就像你的解决方案一样。但后来我将存储库中的那些行移动到每个相应的hibernate监听器中,因此可用性没有变化。
我需要照顾的其他事情:
由于审计(审计实体创建了自己的表,并且它确实通过了侦听器,但由于它没有自己的java类型,因此1)必须在调用侦听器之前进行实体检查。它来自一个地图。所以我得到了一个ClassCastException。2)我必须动态更新状态。没有太多细节,但这就是我所说的:PreInsertEventListener object modifications not sticky
由于我的听众是通用的,我不能对新值进行硬编码,因此我了解了Hibernate如何创建状态数组并重新创建并覆盖它。
最终代码现在看起来像这样:
@Component
public class HibernatePreInsertEventListener<T extends Entity> implements HibernateEventListener, PreInsertEventListener {
@Autowired
private Persister persister;
@SuppressWarnings("unchecked")
@Override
public boolean onPreInsert(PreInsertEvent event) {
Object someEntity = event.getEntity();
if(Entity.class.isAssignableFrom(someEntity.getClass())) {
T entity = (T) someEntity;
Class<T> entityClass = (Class<T>) entity.getClass();
persister.beforeCreateListenersFor(entityClass).execute(entity);
updateState(event);
}
return false;
}
private void updateState(PreInsertEvent event) {
Object[] newState = event.getPersister().getPropertyValuesToInsert(event.getEntity(), null, event.getSession());
for (int i = 0; i < newState.length; i++) {
Object o = newState[i];
event.getState()[i] = o;
}
}
}