2013-08-28 3 views
3

Я хочу регистрировать изменения в учетной записи. Поэтому я создал класс сущности, который должен регистрировать изменения. Каждый раз, когда объект регистрации сохраняется или обновляется, создается объект ведения журнала.Обновить объект и получить старое значение через JPA

Когда объект обновляется с новым балансом, старый баланс извлекается из базы данных. Поскольку объект привязан к сеансу, извлечение его старого баланса не является тривиальным, поскольку каждый всегда получает новый баланс.

Чтобы обойти, я отделил объект от сеанса. Тем не менее, это, кажется, обходное решение, которого следует избегать.

Следующие фрагменты кода должны иллюстрировать сценарий.

Любое предложение высоко ценится!

Тест:

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<ChangeAccountLog> changeResultLogs = this.changeAccountService.findAll(); 
     assertThat(changeResultLogs.get(1).getNewBalance(), is(not(changeResultLogs.get(1).getOldBalance()))); 
    } 
} 

Служба класса домена быть зарегистрированным:

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

Служба класса регистрации:

@Service 
public class ChangeAccountService 
{ 
    @Autowired 
    AccountService    accountService; 

    @Autowired 
    ChangeAccountLogRepository repository; 

    public ChangeAccountLog save(final ChangeAccountLog changeAccountLog) 
    { 
     return this.repository.save(changeAccountLog); 
    } 

    public List<ChangeAccountLog> 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; 

    } 
} 

Класс, какие объекты должны быть зарегистрированы:

@Data 
@NoArgsConstructor 
@AllArgsConstructor 
@Entity 
public class Account 
{ 
    @Id 
    @GeneratedBalance 
    protected long id; 

    Double balance; 
} 

Каротаж класс:

@Data 
@NoArgsConstructor 
@AllArgsConstructor 
@Entity 
public class ChangeAccountLog 
{ 
    @Id 
    @GeneratedBalance 
    private long  id; 

    private Double oldBalance; 
    private Double newBalance; 
} 
+0

Вместо запроса для этого, почему бы не просто кэшировать старый баланс в объекте Account в поле переходного процесса и очистить его при создании ChangeAccountLog из него. – Chris

ответ

0

Вы можете использовать Hibernate Envers создать таблицу версий вместо того, чтобы создавать отдельные объекты журнала.

+0

Хорошее предложение, но устаревшее приложение предоставляет заданную структуру таблицы. – Jochen