Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hibernate实体的触摸等价物_Java_Hibernate_Jpa_Sql Update - Fatal编程技术网

Java Hibernate实体的触摸等价物

Java Hibernate实体的触摸等价物,java,hibernate,jpa,sql-update,Java,Hibernate,Jpa,Sql Update,我想实现repository方法voidtouch(myentitymyentity),该方法强制对实体列进行SQL调用,将其更新为当前值。(背后的原因是更新时的触发器,需要在某个执行点调用该触发器。)理想用例是: void serviceMethod(Long myEntityId) { MyEntity myEntity = myEntityRepository.findOne(myEntityId); ... myEntityRepository.touch(myE

我想实现repository方法
voidtouch(myentitymyentity)
,该方法强制对实体列进行SQL调用,将其更新为当前值。(背后的原因是更新时的
触发器,需要在某个执行点调用该触发器。)理想用例是:

void serviceMethod(Long myEntityId) {
    MyEntity myEntity = myEntityRepository.findOne(myEntityId);
    ...
    myEntityRepository.touch(myEntity);
    ...
}
已经有一些类似的问题对我不起作用了:(我的实体是分离的),(做一些无害的更改工作,但不是一般性的,对代码可读性有不良影响),(类似的例子)

我知道会话侦听器方法
finddrity
以及
customentitydirtinesstrategy
中都有介绍。但是,似乎要使用
findderty
我必须重写会话拦截器,这在存储库方法中是不可能的,因为拦截器是会话创建时分配给会话的最终字段。而
customentitydirtinesstrategy
来自全局的
SessionFactory
。我需要一个一次性解决方案来暂时考虑一个具体类脏的一个具体实体。 到目前为止,最好的解决方案是将无效(空数组)实体快照设置到持久性上下文中,以便
flush()
中的后续逻辑将实体评估为不同于快照,并强制更新。这项工作:

@Override
@Transactional
public void touch(final T entity) {
    SessionImpl session = (SessionImpl)em.getDelegate();
    session.update(entity);
    StatefulPersistenceContext pctx = (StatefulPersistenceContext) session.getPersistenceContext();
    Serializable id = session.getIdentifier(entity);
    EntityPersister persister = session.getEntityPersister(null, entity);
    EntityKey entityKey = session.generateEntityKey(id, persister);
    int length = persister.getPropertyNames().length;
    Field entitySnapshotsByKeyField = FieldUtils.getField(pctx.getClass(), "entitySnapshotsByKey", true);
    Map<EntityKey,Object> entitySnapshotsByKey = (Map<EntityKey,Object>)ReflectionUtils.getField(entitySnapshotsByKeyField, pctx);
    entitySnapshotsByKey.put(entityKey, new Object[length]);
    session.flush();
    em.refresh(entity);
}
@覆盖
@交易的
公共无效接触(最终T实体){
SessionImpl session=(SessionImpl)em.getDelegate();
更新(实体);
StatefulPersistenceContext pctx=(StatefulPersistenceContext)会话。getPersistenceContext();
可序列化id=session.getIdentifier(实体);
EntityPersister=session.getEntityPersister(null,entity);
EntityKey EntityKey=session.generateEntityKey(id,persister);
int length=persister.getPropertyNames().length;
Field EntitySnapshotsByField=FieldUtils.getField(pctx.getClass(),“entitySnapshotsByKey”,true);
Map entitySnapshotsByKey=(Map)ReflectionUtils.getField(EntitySnapshotsByField,pctx);
entitySnapshotsByKey.put(entityKey,新对象[length]);
session.flush();
em.refresh(实体);
}
中的建议对我不起作用,因为
session.execute(entity)
完全清除
entitySnapshotsByKey
条目,这会导致后续的
org.hibernate.event.internal.DefaultFlushentyEventListener#getDatabaseSnapshot
从db加载新的实体。这个问题已经9年了,我不确定它是否适用于当前版本的Hibernate(我的是5.2.17)


不过,我对这种老套的解决方案并不满意。有什么简单的方法或更简单的方法吗?

为什么不使用本机SQL更新?@SimonMartinelli可能是因为我太专注于“强制更新…”问题的解决方案:-)。原生SQL实际上是个好主意。想想从Hibernate元数据合成
更新my_entity set id=id,其中id=1
命令会有多复杂,特别是对于具有复合键的实体等。