title: Update object and get old value via JPA
body: <p>I want to log changes of an account. Therefore, I have created an entity class that shall log the changes.
  Each time, an account entity is saved or updated a logging object is created.</p>
  
  <p>When the object is updated with a new balance the old balance shall be retrieved from the database.
  As the object is bound to the session retrieving its old balance is not trivial, because one always gets the new balance.</p>
  
  <p>To circumvent, I detached the object from the session. Yet, this seems to be a workaround that should be avoided.</p>
  
  <p>The following code snippets shall illustrate the scenario.</p>
  
  <p>Any suggestion is highly appreciated!</p>
  
  <p>The test:</p>
  
  <pre><code>public class AccountServiceTest
  {
      @Autowired
      AccountService        accountService;
  
      @Autowired
      ChangeAccountService  changeAccountService;
  
      @Test
      public void shouldHaveChangeLog()
      {
          Account account = this.accountService.updateAccount(new Account(0, 10.0));
          assertThat(account.getId(), is(not(0L)));
  
          account.setBalance(20.0);
          account = this.accountService.updateAccount(account);
  
          final List&lt;ChangeAccountLog&gt; changeResultLogs = this.changeAccountService.findAll();
          assertThat(changeResultLogs.get(1).getNewBalance(), is(not(changeResultLogs.get(1).getOldBalance())));
      }
  }
  </code></pre>
  
  <p>The service of the domain class to be logged:</p>
  
  <pre><code>@Service
  public class AccountService
  {
      @Autowired
      AccountRepository accountRepository;
  
      @Autowired
      ChangeAccountService  changeAccountService;
  
      public Account findById(final long id)
      {
          return this.accountRepository.findOne(id);
      }
  
      public Account updateAccount(final Account account)
      {
          this.changeAccountService.saveLog(account);
  
          return this.accountRepository.save(account);
      }
  }
  </code></pre>
  
  <p>The service of the logging class:</p>
  
  <pre><code>@Service
  public class ChangeAccountService
  {
      @Autowired
      AccountService                accountService;
  
      @Autowired
      ChangeAccountLogRepository    repository;
  
      public ChangeAccountLog save(final ChangeAccountLog changeAccountLog)
      {
          return this.repository.save(changeAccountLog);
      }
  
      public List&lt;ChangeAccountLog&gt; findAll()
      {
          return this.repository.findAll();
      }
  
      public ChangeAccountLog saveLog(final Account account)
      {
          final Double oldAccountBalance = oldAccountBalance(account);
          final Double newAccountBalance = account.getBalance();
          final ChangeAccountLog changeAccountLog = new ChangeAccountLog(0, oldAccountBalance, newAccountBalance);
  
          return this.repository.save(changeAccountLog);
      }
  
      @PersistenceContext
      EntityManager   em;
  
      private Double oldAccountBalance(final Account account)
      {
          this.em.detach(account);
  
          final Account existingAccount = this.accountService.findById(account.getId());
  
          if (existingAccount != null)
          {
              return existingAccount.getBalance();
          }
          return null;
  
      }
  }
  </code></pre>
  
  <p>The class of which objects are to be logged:</p>
  
  <pre><code>@Data
  @NoArgsConstructor
  @AllArgsConstructor
  @Entity
  public class Account
  {
       @Id
       @GeneratedBalance
       protected    long    id;
  
       Double balance;
  }
  </code></pre>
  
  <p>The logging class:</p>
  
  <pre><code>@Data
  @NoArgsConstructor
  @AllArgsConstructor
  @Entity
  public class ChangeAccountLog
  {
       @Id
       @GeneratedBalance
       private long     id;
  
       private Double    oldBalance;
       private Double    newBalance;
  }
  </code></pre>