3

アカウントの変更をログに記録したい。したがって、変更をログに記録するエンティティ クラスを作成しました。アカウント エンティティが保存または更新されるたびに、ログ オブジェクトが作成されます。

オブジェクトが新しい残高で更新されると、古い残高がデータベースから取得されます。オブジェクトはセッションにバインドされているため、常に新しいバランスを取得するため、古いバランスを取得することは簡単ではありません。

回避するために、セッションからオブジェクトを切り離しました。ただし、これは避けるべき回避策のようです。

次のコード スニペットは、シナリオを示しています。

どんな提案でも大歓迎です!

テスト:

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;
}
4

1 に答える 1

0

個別のログ オブジェクトを作成する代わりに、Hibernate Envers を使用してバージョン管理テーブルを作成することをお勧めします。

于 2013-08-28T13:30:29.127 に答える