区分用户和框架设置值?

时间:2015-11-09 13:43:30

标签: hibernate persistence spring-data-jpa

我使用的是Spring Data 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值在重新获取时将是未知的(取决于调用setter的Hibernate的顺序)。

如果我知道Hibernate正在调用setTotalPages(),那么我可以避免重置remainingPages。有没有办法做到这一点?

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

1 个答案:

答案 0 :(得分:0)

据我所知,有两种选择:

  1. 正如您已经提到的,您可以提供没有副作用的私人制定者。但在这种情况下,我会以不同的方式调用公共方法:

    private void setTotalPages(int totalPages) {
      this.totalPages = totalPages;
    }
    
    public void resetTotalPages(int totalPages) {
      this.totalPages = totalPages;
      this.remainingPages = totalPages;
    }
    
  2. 您可以使用@PostLoad在Hibernate完全初始化对象后立即设置标记:

    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);
        }
      }
    
      ...
    
    }