【问题标题】:How to override @CreatedBY value from AbstractAuditingEntity in Spring JPA如何在 Spring JPA 中覆盖 AbstractAuditingEntity 的 @CreatedBY 值
【发布时间】:2017-11-29 18:27:05
【问题描述】:

我们有一个微网络服务环境,其中 AbstractAuditingEntity 来自另一个常见的微服务。我想用我自己定义的值覆盖这个抽象类的@CreatedBy 属性。

我的代码如下。

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class AbstractAuditingEntity {

@Column(name = "created_by", insertable = true, updatable = false,     nullable = false)
@CreatedBy
private String createdBy;

@Column(name = "created_date", insertable = true, updatable = false, nullable = false)
@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime")
@CreatedDate
private DateTime createdDate;

@Column(name = "last_modified_by", nullable = false)
@LastModifiedBy
private String lastModifiedBy;

@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime")
@LastModifiedDate
private DateTime lastModifiedDate;

// @Transient
public abstract Long getInternalId();

// @Transient
public abstract void setInternalId(Long internalId);

public DateTime getCreatedDate() {
return createdDate;
}

public void setCreatedDate(DateTime createdDate) {
this.createdDate = createdDate;
}

public DateTime getLastModifiedDate() {
return lastModifiedDate;
}

public void setLastModifiedDate(DateTime lastModifiedDate) {
this.lastModifiedDate = lastModifiedDate;
}

public String getCreatedBy() {
return createdBy;
}

public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}

public String getLastModifiedBy() {
return lastModifiedBy;
}

public void setLastModifiedBy(String lastModifiedBy) {
this.lastModifiedBy = lastModifiedBy;
}
}

我的域类就像

@Entity
@Table(name = "programs")
 @AttributeOverride(name = "createdBy", column = @Column(name = "created_by"))
public class Program extends AbstractAuditingEntity {

 @Id
 @SequenceGenerator(name = "programs_seq", sequenceName = "programs_seq")
 @GeneratedValue(generator = "programs_seq")
 @Column(name = "internal_id", nullable = false)
 private Long internalId;

 private String programName;  

 @Override
 public String toString() {
    return ToStringBuilder.reflectionToString(this,    ToStringStyle.MULTI_LINE_STYLE);
 }
//Start getters & setters - auto generated by IDE

 @Override
 public Long getInternalId() {
   return internalId;
 }

 @Override
  public void setInternalId(Long internalId) {
    this.internalId = internalId;
  }

  public String getProgramName() {
    return programName;
  }

  public void setProgramName(String programName) {
   this.programName = programName;
  }

}

当我们尝试在数据库中持久化这个域对象时,我提供的用户定义的值没有得到持久化,而是 Spring 框架仍然添加自己的值。我已经尝试过@AttributeOverride,但在我的情况下它不起作用。

提前感谢您的帮助。

【问题讨论】:

    标签: spring hibernate hibernate-envers


    【解决方案1】:

    我得到了如下解决方案。

    @PrePersist
    private void setCreateByNew() {
       setCreatedBy("anonymousUser");     
    }
    

    使用 @PrePersist 我可以覆盖从通用框架中获得的值。

    【讨论】:

      【解决方案2】:

      另一种解决方案是设置 securityContext SecurityContextHolder.getContext().setAuthentication(___{AuthToken}___)

      使用您用于在实体保存之前自动填充审计字段并在之后重置它的用户名/主体。 (用于异步方式的消息或事件处理)。这将填充来自 JPA AuditAware 侦听器的 @Createdby@LastUpdatedBy

      @PrePersist 仅在我们尝试硬编码预定义字符串 setCreatedBy("anonymousUser"); 时才有效,如上所述。它不允许我们将用户的用户名/名称作为参数传递给方法。

      【讨论】:

        【解决方案3】:

        for : 我提供的用户定义值没有得到持久化,而是 Spring 框架仍在添加自己的值

        您可以使用 AuditorAware 界面来完成。 3.1.3 AuditorAware

        如果您使用@CreatedBy 或@LastModifiedBy,审计 基础设施需要以某种方式了解当前的委托人。 为此,我们提供了一个 AuditorAware SPI 接口,您必须 实现告诉基础设施当前用户或系统是谁 与应用程序的交互是。泛型类型 T 定义的 用@CreatedBy 或@LastModifiedBy 注释的属性是什么类型 必须的。

        这是一个使用 Spring 实现接口的示例 安全的 Authentication 对象:

        示例 3.2。基于Spring Security实现AuditorAware

        class SpringSecurityAuditorAware implements AuditorAware<User> {
        
          public User getCurrentAuditor() {
        
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        
            if (authentication == null || !authentication.isAuthenticated()) {
              return null;
            }
        
            return ((MyUserDetails) authentication.getPrincipal()).getUser();
          }
        }
        

        【讨论】:

        • 请注意,不使用 Spring 的自然方法是创建一个 RevisionEntityListener 并在 Envers 构造它之后在修订实体实例上设置值。以上基本上是 Spring 对该特性的封装。
        • 我知道这种情况。但是所有这些配置和 AuditorAware 接口都是在许多其他服务使用的公共服务中实现的。现在,我当前的 CreatedBy 和 Updatedby 值仅以这种方式出现。但是我想在我的个人服务中用不同的值覆盖这个值,有什么办法可以做到这一点。谢谢你的建议。但我正在寻找更多解决方案。
        猜你喜欢
        • 2015-06-10
        • 1970-01-01
        • 2019-01-21
        • 1970-01-01
        • 1970-01-01
        • 2018-06-25
        • 2013-08-02
        • 2017-01-26
        • 2016-01-26
        相关资源
        最近更新 更多