克隆 JPA 实体,包括用 spring 的 createdBy 注释的值
Posted
技术标签:
【中文标题】克隆 JPA 实体,包括用 spring 的 createdBy 注释的值【英文标题】:Cloning JPA entity including value annotated with spring's createdBy 【发布时间】:2019-01-21 04:40:39 【问题描述】:我有以下超类(抽象)
public abstract class AbstractAuditEntity
@CreatedBy
private String createdBy;
我的数据库中有几个对象。现在我想要一种方法来克隆特定对象及其所有属性,包括 createdBy。我可以将任何 String 设置为此值,但该值会在持久化到数据库之前重置为当前经过身份验证的用户名。
如何防止 spring/jpa 在已填充时覆盖我的 createdBy 字段?
提前致谢!
【问题讨论】:
【参考方案1】:不幸的是,这似乎是不可能的。
在 AuditingEntityListener 中,@PrePersist 方法如下所示:
@PrePersist
public void touchForCreate(Object target)
Assert.notNull(target, "Entity must not be null!");
if (handler != null)
AuditingHandler object = handler.getObject();
if (object != null)
object.markCreated(target);
然后是 AuditingHandler:
public <T> T markCreated(T source)
Assert.notNull(source, "Entity must not be null!");
return touch(source, true);
由于第二个参数为真,它总是会设置 createdBy 字段:
private Optional<Object> touchAuditor(AuditableBeanWrapper<?> wrapper, boolean isNew)
Assert.notNull(wrapper, "AuditableBeanWrapper must not be null!");
return auditorAware.map(it ->
Optional<?> auditor = it.getCurrentAuditor();
Assert.notNull(auditor,
() -> String.format("Auditor must not be null! Returned by: %s!", AopUtils.getTargetClass(it)));
auditor.filter(__ -> isNew).ifPresent(foo -> wrapper.setCreatedBy(foo));
auditor.filter(__ -> !isNew || modifyOnCreation).ifPresent(foo -> wrapper.setLastModifiedBy(foo));
return auditor;
);
但由于这似乎是一个有趣的功能,您应该继续并打开未来的请求: https://jira.spring.io/projects/DATAJPA/issues/DATAJPA-1397?filter=allopenissues
【讨论】:
是的,我看到了 touchAuditor-Method。所以解决这个问题的唯一方法(到目前为止)是在没有 jpa 的情况下将对象直接保存到数据库,对吧?不过,谢谢你的回答! 是的,或者您创建自己的 JPA 侦听器并设置用户。【参考方案2】:我为 DataJPA 创建了一个功能请求,但我不知道它何时(如果)得到解决。
在此之前,我先保存实体并使用本机 SQL 更改 createdBy。我不会将此标记为已接受的答案。
public interface EntityRepository
@Transactional(propagation = NESTED)
@Modifying
@Query(value = "UPDATE entity_table SET created_by = ? WHERE id = ?", nativeQuery = true)
void updateSignalRequestCreatedBy(String createdBy, long signalRequestId);
Source DataJPA-Request
【讨论】:
以上是关于克隆 JPA 实体,包括用 spring 的 createdBy 注释的值的主要内容,如果未能解决你的问题,请参考以下文章
Spring/JPA/persistence 实体属性字段不能是最终的?
Spring Data JPA - “找不到类型的属性”异常
Spring Data JPA中使用QueryDSL进行查询
spring jpa之实体属性类型转换器AttributeConverter,自定义Converter,通用Converter