我有一个 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/