区分用户和框架设置值?

Distinguish between user and framework setting values?

我正在使用 Spring 数据 JPA/Hibernate 并且我有一个执行倒计时的持久性工作对象。它使用 2 个 int 值建模:totalPagesremainingPages。创建对象时,它确保 total == remaining,并且每次处理一个页面时,remainingPages 都会递减:

@Entity
@Access(AccessType.PROPERTY)
public class WorkerState {
  private int totalPages;

  private int remainingPages;

  /** Constructor for JPA. */
  protected WorkerState() {
  }

  public WorkerState(int totalPages) {
    setTotalPages(totalPages);
  }

  private void setRemainingPages(int remainingPages) {
    this.remainingPages = remainingPages;
  }

  public void setTotalPages(int totalPages) {
    this.totalPages = totalPages;
    setRemainingPages(totalPages);
  }

  public void decrementRemainingPages() {
    this.remainingPages--;
  }

}

目前,setTotalPages() 也调用了 setRemainingPages()。但是,我认为如果在处理过程中保留对象,这会让我遇到麻烦。如果 remainingPages 小于 totalPages 并且对象被持久化,当重新获取时 remainingPages 值将是未知的(取决于 Hibernate 调用 setter 的顺序)。

如果我知道 Hibernate 正在调用 setTotalPages(),那么我就可以避免重置 remainingPages。有办法吗?

一个想法是让 public 方法调用 addToPages() 并使 setTotalPages 方法像 setRemainingPages 一样私有。唯一的缺点是设置任意总数的奇怪语义 (addToPages(myNewTotal-getTotalPages())),但我想这不是我见过的最糟糕的事情。

据我所知有两种选择:

  1. 正如您已经提到的,您可以提供一个没有副作用的私有 setter。但在那种情况下,我会以不同的方式调用 public 方法:

    private void setTotalPages(int totalPages) {
      this.totalPages = totalPages;
    }
    
    public void resetTotalPages(int totalPages) {
      this.totalPages = totalPages;
      this.remainingPages = totalPages;
    }
    
  2. 您可以在 Hibernate 使用 @PostLoad:

    完全初始化您的对象后立即设置标记
    public class WorkerState {
      private boolean initialized;
    
      ...
    
      public WorkerState(int totalPages) {
        initialized = true;
        setTotalPages(totalPages);
      }
    
      @PostLoad
      private void init() {
        this.initialized = true;
      }
    
      public void setTotalPages(int totalPages) {
        this.totalPages = totalPages;
        if (initialized) {
          setRemainingPages(totalPages);
        }
      }
    
      ...
    
    }