【问题标题】:Approve modification on entity before publish在发布前批准对实体的修改
【发布时间】:2020-04-22 19:57:14
【问题描述】:

我正在尝试创建一个系统,该系统需要管理员在发布之前批准对实体的修改。该系统是一个 REST API,其身份验证/授权已经在工作,因此该部分并不重要。假设我们有一个描述文章的模型,带有标题和正文。普通用户可以修改所有字段,但在文章发布之前,必须得到管理员的批准。但是当文章处于“批准模式”时,文章的旧版本必须可以通过 REST API 访问,以便至少有一个可以工作的版本(并且 API 不会返回 404)。

要求是:

  • 我正在使用 Spring Data 和 PostgreSQL,所以在集成它的同时让我不那么头痛的是我要使用的那个
  • 奇怪的支票越少修补越好
  • 如果可能,它应该可以修改以与其他实体一起使用
  • 如果可能,我想保留旧版本以及修改者。非必需品,但会很好

我有两种不同的想法,但我不确定哪一种是最好的:

  1. 创建一个抽象父类,然后用批准和未批准的版本对其进行扩展。然后,当修改被批准时,实体被转换为被批准的实体,API 将返回新版本:
    public abstract class Article {}
    public class ApprovedArticle extends Article {}
    public class ModifiedArticle extends Article {}
  1. 创建一个单独的表来存储修改后的实体,并将视图限制为仅限管理员。在这种情况下,我将隔离这两种类型并使其在获取信息时更容易。但是这样我就失去了“历史”,我需要从两个不同的位置获取。
  2. 简单的布尔标志:这是我最后的手段,我很想避免它!

有没有更好的方法或者我应该使用概述的示例之一?

谢谢!

【问题讨论】:

    标签: postgresql spring-boot jackson spring-data


    【解决方案1】:

    查看 Spring Auditing。

    https://www.baeldung.com/database-auditing-jpa

    所以有一个想法: 对于每个表,您都有一个历史表,每个历史表都有 REVTYPE(“0”用于添加,“1”用于更新,“2”用于删除实体) 和 REV(更改编号) 列。 除此之外,您还需要默认生成一个名为 REVINFO 的额外表,以获取您需要扩展默认 DefaultRevisionEntity 类的用户详细信息。

    @Entity
    @RevisionEntity(YOURRevisionListener.class)
    @Table(name = "your_audit_info")
    @AttributeOverrides(
        {@AttributeOverride(name = "timestamp", column = @Column(name = "REVTSTMP")),
                @AttributeOverride(name = "id", column = @Column(name = "REV"))})
    
        public class AuditInfo extends DefaultRevisionEntity
        {
            private static final long serialVersionUID = 8458400378132903089L;
            @Column(name = "UpdateUser", nullable = false)
            private String userName;
    
            public String getUserName()
            {
                return userName;
            }
    
            public void setUserName(
                final String userName)
            {
                this.userName = userName;
            }
    
        }
    

    通过审核设置,如果更改得到管理员批准,您将获得用户详细信息,然后比较操作开始时的修订号和操作批准以避免被其他人覆盖。

     @PrePersist
        public void onPrePersist() {
            audit("INSERT");
        }
    
        @PreUpdate
        public void onPreUpdate() {
            audit("UPDATE");
        }
    
        @PreRemove
        public void onPreRemove() {
            audit("DELETE");
        }
    

    我知道这是一种非常高级的方法,但它可以在你的情况下工作

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-21
      • 1970-01-01
      • 2017-02-22
      • 1970-01-01
      • 2017-10-27
      • 2014-09-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多