私はカスタムValidatorがあなたのケースでは正しい選択だと思います。
まず - それはその前の状態を保存するためにあなたのエンティティを更新(@AlanHayのおかげで):
@Entity
class ItemEntity {
@Transient
private ItemEntity previousState;
@PostLoad
private void setPreviousState(){
previousState = new ItemEntity();
//copy the fields
}
public ItemEntity getPreviousState(){
return previousState;
}
}
はその後、いくつかの「権威」を持つ現在のユーザがフィールドを変更したかどうかをチェックするバリデータを実装します。
public class ItemValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
//...
}
@Override
public void validate(Object target, Errors errors) {
Collection<? extends GrantedAuthority> authorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities();
SimpleGrantedAuthority userRole = new SimpleGrantedAuthority("ROLE_USER");
if (authorities.contains(userRole)) {
ItemEntity item = (ItemEntity) target;
prevItem = item.getPreviousState();
String prevName = prevItem.getName();
String prevCreator = prevItem.getCreator();
String newName = item.getName();
String newCreator = item.getCreator();
if (!prevName.equals(newName)) {
errors.rejectValue("name", "You cannot change Name field!");
}
if (!prevCreator.equals(newCreator)) {
errors.rejectValue("creator", "You cannot change Creator field!");
}
}
// Other checks...
}
}
そしてRepositoryRestConfigurerAdapter
プラグでこのバリ:
@Configuration
public class RepoRestConfig extends RepositoryRestConfigurerAdapter {
@Override
public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener v) {
v.addValidator("beforeCreate", itemValidator()); // POST (if needed)
v.addValidator("beforeSave", itemValidator()); // PUT/PATCH
super.configureValidatingRepositoryEventListener(v);
}
@Bean
ListingValidator itemValidator() {
return new ItemValidator();
}
}
これはうまくいくはずだと思います...
RESTリポジトリイベントを試しましたか? @HandleBeforeSaveイベントなどのように? –
はい、問題は、ハンドラに渡されるアイテムが、PUTリクエストを介して渡されたアイテムに変更されていることです。 – Florian
そして、データベース層の変更を処理することは可能ですか(たとえば、mysqlをupdateable = falseに設定している場合)? –