使用 Spring 数据 REST 存储库时,如何确定 RESTful 资源的哪些属性在保存之前已更改?
How to determine which properties of a RESTful resource have changed before save when using Spring Data REST repositories?
如果我有以下由 Spring Data REST 发布的资源...
{ "status": "idle" }
我如何应对更改 属性 status
值的 PATCH 或 PUT?这个想法是根据 属性 更改触发一些服务器进程。
理想情况下,这会在保存之前发生,并且可以将资源的新版本与以前保留的版本进行比较。
您通常会使用 @RepositoryEventHandler
来连接您的事件逻辑 - 请参阅 documentation for details。
我不知道有什么函数可以直接获取更改后的属性。但是,如果您使用 HandleBeforeSave
处理程序,您可以加载持久实体(旧状态)并将其与新状态进行比较 -
@RepositoryEventHandler
@Component
public class PersonEventHandler {
...
@PersistenceContext
private EntityManager entityManager;
@HandleBeforeSave
public void handlePersonSave(Person newPerson) {
entityManager.detach(newPerson);
Person currentPerson = personRepository.findOne(newPerson.getId());
if (!newPerson.getName().equals(currentPerson.getName)) {
//react on name change
}
}
}
请注意,您需要将 newPerson 从当前的 EntityManager 中分离出来。否则我们会在调用 findOne 时获得缓存的 person 对象 - 我们无法将更新版本与当前数据库状态进行比较。
如果使用 Eclipselink
如果您使用的是 eclipselink,您还可以更有效地找出已应用于您的实体的更改,从而避免重新加载 - 请参阅 here for details
UnitOfWorkChangeSet changes = entityManager.unwrap(UnitOfWork.class).getCurrentChanges();
ObjectChangeSet objectChanges = changes.getObjectChangeSetForClone(newPerson);
List<String> changedAttributeNames = objectChanges.getChangedAttributeNames();
if (objectChanges.hasChangeFor("name")) {
ChangeRecord changeRecordForName = objectChanges.getChangesForAttributeNamed("name");
String oldValue = changeRecordForName.getOldValue();
}
如果我有以下由 Spring Data REST 发布的资源...
{ "status": "idle" }
我如何应对更改 属性 status
值的 PATCH 或 PUT?这个想法是根据 属性 更改触发一些服务器进程。
理想情况下,这会在保存之前发生,并且可以将资源的新版本与以前保留的版本进行比较。
您通常会使用 @RepositoryEventHandler
来连接您的事件逻辑 - 请参阅 documentation for details。
我不知道有什么函数可以直接获取更改后的属性。但是,如果您使用 HandleBeforeSave
处理程序,您可以加载持久实体(旧状态)并将其与新状态进行比较 -
@RepositoryEventHandler
@Component
public class PersonEventHandler {
...
@PersistenceContext
private EntityManager entityManager;
@HandleBeforeSave
public void handlePersonSave(Person newPerson) {
entityManager.detach(newPerson);
Person currentPerson = personRepository.findOne(newPerson.getId());
if (!newPerson.getName().equals(currentPerson.getName)) {
//react on name change
}
}
}
请注意,您需要将 newPerson 从当前的 EntityManager 中分离出来。否则我们会在调用 findOne 时获得缓存的 person 对象 - 我们无法将更新版本与当前数据库状态进行比较。
如果使用 Eclipselink
如果您使用的是 eclipselink,您还可以更有效地找出已应用于您的实体的更改,从而避免重新加载 - 请参阅 here for details
UnitOfWorkChangeSet changes = entityManager.unwrap(UnitOfWork.class).getCurrentChanges();
ObjectChangeSet objectChanges = changes.getObjectChangeSetForClone(newPerson);
List<String> changedAttributeNames = objectChanges.getChangedAttributeNames();
if (objectChanges.hasChangeFor("name")) {
ChangeRecord changeRecordForName = objectChanges.getChangesForAttributeNamed("name");
String oldValue = changeRecordForName.getOldValue();
}