zhangzhenhuajack / spring-data-jpa-guide

spring-data-jpa-guide,Spring Data JPA实战,SpringDataJpa详解
http://www.jackzhang.cn/spring-data-jpa-guide/
379 stars 164 forks source link

利用AuditingEntityListener在insert之前把请求header里面的租户ID和工作空间更新到通用字段里面 #59

Open zhangzhenhuajack opened 8 months ago

zhangzhenhuajack commented 8 months ago
  1. 新增自己的AuditingEntityListener
    
    package com.mega.workflow.suite.common;

import org.springframework.beans.factory.ObjectFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.auditing.AuditingHandler; import org.springframework.data.domain.Auditable; import org.springframework.stereotype.Component; import org.springframework.util.Assert; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes;

import javax.persistence.PrePersist; import javax.persistence.PreUpdate; import java.util.Optional;

import static com.mega.workflow.suite.common.Constant.HEADER_TENANT_ID; import static com.mega.workflow.suite.common.Constant.WORKSPACE_CODE_HEADER;

@Component public class MegaAuditingEntityListener{ @Autowired private ObjectFactory handler;

/**
 * Sets modification and creation date and auditor on the target object in case it implements {@link Auditable} on
 * persist events.
 *
 * @param target
 */
@PrePersist
public void touchForPreCreate(Object target) {

    Assert.notNull(target, "Entity must not be null!");

    if (handler != null) {

        AuditingHandler object = handler.getObject();
        if (object != null) {
            object.markCreated(target);
        }

        if (target instanceof BaseEntity) {
            //更新工作空间到基础字段里面
            String workspaceCode = Optional.ofNullable(((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getHeader(WORKSPACE_CODE_HEADER)).orElse("molclone");
            BaseEntity baseEntity = (BaseEntity) target;
            baseEntity.setWorkspaceCode(workspaceCode);

            //更新租户ID到基础字段里面
            String tenantId = Optional.ofNullable(((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getHeader(HEADER_TENANT_ID)).orElse("-1");
            baseEntity.setTenantId(tenantId);
        }
    }
}
/**
 * Sets modification and creation date and auditor on the target object in case it implements {@link Auditable} on
 * update events.
 *
 * @param target
 */
@PreUpdate
public void touchForUpdate(Object target) {

    Assert.notNull(target, "Entity must not be null!");

    if (handler != null) {

        AuditingHandler object = handler.getObject();
        if (object != null) {
            object.markModified(target);
        }
    }
}

}

2. BaseEntity的内容如下:

package com.mega.workflow.suite.common;

import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; import org.hibernate.annotations.Comment; import org.springframework.data.annotation.CreatedBy; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedBy; import org.springframework.data.annotation.LastModifiedDate;

import javax.persistence.*; import javax.validation.constraints.Min; import java.time.Instant;

@Data @MappedSuperclass @EntityListeners({MegaAuditingEntityListener.class}) @SuperBuilder(toBuilder = true) @AllArgsConstructor @NoArgsConstructor public abstract class BaseEntity { @Id @GeneratedValue(strategy= GenerationType.IDENTITY) // @GenericGenerator(name = "snowFlakeIdGenerator", strategy = "com.mega.workflow.suite.common.SnowFlakeIdGenerator") // @GeneratedValue(generator = "snowFlakeIdGenerator") @Comment("主键") @Column(name = "id", nullable = false) @Min(value = 1, message = "主键必须大于0") @ApiModelProperty("主键") private Long id;

@Comment("创建者")
@CreatedBy
@Convert(disableConversion = true)
@Column(name = "created_by")
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
@ApiModelProperty("创建者")
private Long createdBy;

@Transient
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private String createdByUserName;

@Comment("创建时间")
@CreatedDate
@Column(name = "created_date")
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
@ApiModelProperty("创建时间")
private Instant createdDate;

@Comment("更新者")
@LastModifiedBy
@Convert(disableConversion = true)
@Column(name = "last_modified_by")
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
@ApiModelProperty("更新者")
private Long lastModifiedBy;

@Comment("更新时间")
@LastModifiedDate
@Column(name = "last_modified_date")
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
@ApiModelProperty("更新时间")
private Instant lastModifiedDate;

@Comment("乐观锁")
@Version
@Column(name = "version")
@ApiModelProperty("乐观锁")
private Integer version;

@Comment("租户ID")
@Convert(disableConversion = true)
@Column(name = "tenant_id")
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
@ApiModelProperty("租户ID")
private String tenantId;

@Comment("逻辑删除")
@Column(name = "deleted")
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
@ApiModelProperty("逻辑删除")
private Boolean deleted;

@Comment("删除时间")
@Column(name = "deleted_date")
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
@ApiModelProperty("删除时间")
private Instant deletedDate;

@Comment("工作空间")
@Convert(disableConversion = true)
@Column(name = "workspace_code")
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
@ApiModelProperty("工作空间")
private String workspaceCode;

@PrePersist
public void prePersist() {
    if (this.id == null || this.id <= 0) {
        this.deleted = false;
        this.deletedDate = Instant.parse("1999-09-02T00:00:00Z");
    }
}

@Transient
public String getCreatedByUserName() {
    if (createdByUserName == null) {
        return "admin";
    }
    return createdByUserName;
}

@Transient
@JsonIgnore
public abstract T getUpdateEntity(T entity);

}


既BaseEntity里面引用@EntityListeners({MegaAuditingEntityListener.class}) 即可;
zhangzhenhuajack commented 8 months ago

参考:https://www.baeldung.com/jpa-entity-lifecycle-events