Java 通过JPA更新对象并获取旧值
我想记录帐户的更改。因此,我创建了一个实体类来记录更改。 每次保存或更新帐户实体时,都会创建一个日志记录对象 当使用新余额更新对象时,应从数据库中检索旧余额。 由于对象绑定到会话,因此检索其旧平衡并不容易,因为总是会获得新平衡 为了避免这种情况,我将对象与会话分离。然而,这似乎是一个应该避免的解决办法 以下代码片段将说明该场景 非常感谢您的任何建议 测试:Java 通过JPA更新对象并获取旧值,java,jpa,spring-data,spring-data-jpa,container-managed,Java,Jpa,Spring Data,Spring Data Jpa,Container Managed,我想记录帐户的更改。因此,我创建了一个实体类来记录更改。 每次保存或更新帐户实体时,都会创建一个日志记录对象 当使用新余额更新对象时,应从数据库中检索旧余额。 由于对象绑定到会话,因此检索其旧平衡并不容易,因为总是会获得新平衡 为了避免这种情况,我将对象与会话分离。然而,这似乎是一个应该避免的解决办法 以下代码片段将说明该场景 非常感谢您的任何建议 测试: public class AccountServiceTest { @Autowired AccountService
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 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 ChangeAccountLog
{
@Id
@GeneratedBalance
private long id;
private Double oldBalance;
private Double newBalance;
}
日志记录类:
@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 ChangeAccountLog
{
@Id
@GeneratedBalance
private long id;
private Double oldBalance;
private Double newBalance;
}
您可能希望使用Hibernate Envers创建版本控制表,而不是创建单独的日志对象。这是一个好建议,但传统应用程序提供了一个给定的表结构。与其查询它,不如将帐户实体中的旧余额缓存在临时字段中,并在从中创建ChangeAccountLog时清除它。