Spring数据在HandleBeforeSave中为null字段

时间:2017-08-28 16:27:59

标签: spring spring-data-jpa spring-data-rest

我正面临一个场景,其中一个实体用户有一个字段密码(除其他外,但这些并不重要)。我想处理两个场景:

  1. 使用密码字段的PUT实际上应该更新提供的密码
  2. 没有密码字段的PUT应保留密码。
  3. 虽然第一种情况正常,但我找不到另一种情况的解决方案。我试过像这样的事件处理程序

        @HandleBeforeSave
        fun handleUserUpdate(user: User) {
            if (user.password == null || user.password == "") {
                val storedUser = systemRunner.runInSystemContext { userRepository.findOne(user.id!!) }
                user.password = storedUser.password
            } else {
                user.password = passwordEncoder.encode(user.password)
            }
        }
    

    但这不起作用。 Spring DATA REST已经将提供的参数中的字段归零(并且它在相同的JPA会话中,所以显然我从DB获得了相同的结果)。我可能会请求刷新实体但是我会松开其他更改?怎么做?

2 个答案:

答案 0 :(得分:0)

这很奇怪......在我的java项目中,PUT和PATCH请求都按预期工作:

@Component
@RepositoryEventHandler(User.class)
public class UserEventHandler {

    @HandleBeforeSave
    public void handleBeforeSave(User user) { // user: "User[id:1]"
        //...
    }
}

但是如何在User类中编码密码呢?例如:

@Entity
public class User {

    public static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();

    //...

    @PreUpdate
    @PrePersist
    private void encodePassword() {
        password = !StringUtils.isEmpty(password) ? ENCODER.encode(password) : null;
    } 
} 

在我看来,这个解决方案更好,因为它不依赖于REST层......

答案 1 :(得分:0)

实际上我找到了anwser。请使用标准内容类型为json的补丁或使用" application / merge-patch + json"。请按照RFC specification说明要将f字段归零并将字段更新为值" z"在

 {
       "a": "b",
       "c": {
           "d": "e",
           "f": "g"
       }
 }

您需要修补" application / merge-patch + json"

       {
         "a":"z",
         "c": {
            "f": null
         }
       }

或者你可以做这样的事情

    @Transient
    var oldPassword: String? = null

    @PostLoad
    fun rememberOldUser() {
        this.oldPassword = this.password;
    }