java - 数据库更新后运行的 PUT 和 PATCH 的 Spring 数据剩余验证

标签 java spring hibernate spring-boot spring-data-rest

我有一个 SDR 项目,并且我成功验证了 POST 请求的用户实体,但是一旦我使用 PATCH 或 PUT 更新现有实体,数据库就会在执行验证之前更新(正在执行 validator 并返回错误,但数据库无论如何都在更新)。

我需要设置单独的配置进行更新吗?我是否缺少一个额外的步骤?

实体

@Entity
@JsonIgnoreProperties(ignoreUnknown = true)
public class Member {

    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "member_id_gen")
    @SequenceGenerator(name = "member_id_gen", sequenceName = "member_id_seq")
    @Id
    @JsonIgnore
    private long id;

    @Version
    private Integer version;

    @NotNull
    protected String firstName;
    @NotNull
    protected String lastName;

    @Valid
    protected String email;

}

存储库

@RepositoryRestResource(collectionResourceRel = "members", path = "member")
public interface MemberRepository extends PagingAndSortingRepository<Member, Long>  {

     public Member findByFirstName(String firstName); 

     public Member findByLastName(String lastName); 

}

validator

@Component
public class BeforeSaveMemberValidator implements Validator {

    public BeforeSaveMemberValidator() {}

    private String EMAIL_REGEX = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,6}$";

    @Override
    public boolean supports(Class<?> clazz) {
        return Member.class.equals(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
        Member member = (Member) target;

        if(ObjectUtils.isEmpty(member.getFirstName())) {
            errors.rejectValue("firstName", "member.firstName.empty");
        }

        if(ObjectUtils.isEmpty(member.getLastName())) {
            errors.rejectValue("lastName", "member.lastName.empty");
        }

        if(!ObjectUtils.isEmpty(member.getDni()) && !member.getDni().matches("^[a-zA-Z0-9]*$")) {
            errors.rejectValue("dni", "member.dni.invalid");
        }

        if(!ObjectUtils.isEmpty(member.getEmail()) && !member.getEmail().matches(EMAIL_REGEX)) {
            errors.rejectValue("email", "member.email.notValid");
        }
    }
}

保存前服务

@Service
@RepositoryEventHandler(Member.class)
public class MemberService {

    @HandleBeforeCreate
    @HandleBeforeSave
    @Transactional
    public void beforeCreate(Member member) {
        ...
    }

}

最佳答案

我认为您应该将 validator 重命名为 MemberValidator,然后按描述分配它 here :

@Override
protected void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener v) {
  v.addValidator("beforeCreate", new MemberValidator());
  v.addValidator("beforeSave", new MemberValidator());
}

但我建议你使用Bean validation而不是您的自定义 validator 。要在 SDR 项目中使用它,您可以注入(inject) LocalValidatorFactoryBean,然后将其分配给 configureValidatingRepositoryEventListener 中的“beforeCreate”和“beforeSave”事件:

@Configuration
@RequiredArgsConstructor // Lombok annotation
public class RepoRestConfig extends RepositoryRestConfigurerAdapter {

    @NonNull private final LocalValidatorFactoryBean validatorFactoryBean;

    @Override
    public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener v) {
        v.addValidator("beforeCreate", validatorFactoryBean);
        v.addValidator("beforeSave", validatorFactoryBean);
        super.configureValidatingRepositoryEventListener(v);
    }
}

在这种情况下,您的 SDR 将自动验证所有公开的 SDR 存储库的 POST、PUT 和 PATCH 请求的有效负载。

查看我的example了解更多详情。

关于java - 数据库更新后运行的 PUT 和 PATCH 的 Spring 数据剩余验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46999658/

相关文章:

java - Spring WebFlux 无法在 Tomcat 中运行

java - 无法从 fragment 调用 Adapter 方法

java - 昨天下载到我电脑上的oracle 11db如何获取sql*plus连接?

Java 模式匹配器未按预期适用于正则表达式

java - 无法模拟 FileInputStream

java.lang.ClassCastException : String can't be cast to Date 异常

java - JAX-RS 中使用 @Required 注解的必需 @QueryParam 在 ContainerRequestFilter 中不起作用

java - IntelliJ IDEA 2017.2.5 : Cannot determine embedded database driver

java - Spring Data/Hibernate 生成两个查询而不是 JOIN

java - 我是否正确配置了 Hibernate hibernate.cfg.xml 文件?