Обновить объект и получить старое значение через 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;
}

1 ответ

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

Другие вопросы по тегам