[英]Update object and get old value via JPA
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.
每次保存或更新帐户实体时都会创建日志记录对象。
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.
由于对象绑定到会话检索其旧余额并不简单,因为总是得到新的余额。
To circumvent, I detached the object from the session. 为了规避,我将对象从会话中分离出来。 Yet, this seems to be a workaround that should be avoided.
然而,这似乎是一个应该避免的解决方法。
The following code snippets shall illustrate the scenario. 以下代码片段将说明该方案。
Any suggestion is highly appreciated! 任何建议都非常感谢!
The test: 考试:
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())));
}
}
The service of the domain class to be logged: 要记录的域类的服务:
@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);
}
}
The service of the logging class: 日志记录类的服务:
@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;
}
}
The class of which objects are to be logged: 要记录哪些对象的类:
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class Account
{
@Id
@GeneratedBalance
protected long id;
Double balance;
}
The logging class: 记录类:
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class ChangeAccountLog
{
@Id
@GeneratedBalance
private long id;
private Double oldBalance;
private Double newBalance;
}
您可能希望使用Hibernate Envers来创建版本控制表,而不是创建单独的日志对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.