t I asked the same question on teratail.Please understand.
https://teratail.com/questions/319227
I am currently using Spring Boot to create a reservation site.
What I want to do now is create my own validation, check if the user ID password is already registered when registering, and display an error message if it is already registered.
development environment:Eclipse
Java version: 11
Spring Boot version: 2.4.0
I created a UserIdDuplicateCheckValidator with ConstraintValidator, where @Autowired and injected UserService instances become null.
java.lang.NullPointerException: null
at mrs.app.user.UserIdDuplicateCheckValidator.isValid(UserIdDuplicateCheckValidator.java:30)~[classes/:na]
at mrs.app.user.UserIdDuplicateCheckValidator.isValid(UserIdDuplicateCheckValidator.java:1)~[classes/:na]
atorg.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateSingleConstraint(ConstraintTree.java:180)~[hibernate-validator-6.1.6.Final.jar:6.1.6.Final]
atorg.hibernate.validator.internal.engine.constraintvalidation.SimpleConstraintTree.validateConstraints (SimpleConstraintTree.java:62) to [hibernate-validator-6.1.6.Final.jar:6.1.6.Final]
atorg.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:75)~[hibernate-validator-6.1.6.Final.jar:6.1.6.Final]
atorg.hibernate.validator.internal.metadata.core.MetaConstraint.doValidateConstraint(MetaConstraint.java:130)~[hibernate-validator-6.1.6.Final.jar:6.1.6.Final]
atorg.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:123)~[hibernate-validator-6.1.6.Final.jar:6.1.6.Final]
atorg.hibernate.validator.internal.engine.ValidatorImpl.validateMetaConstraint (ValidatorImpl.java:555) to [hibernate-validator-6.1.6.Final.jar:6.1.6.Final]
atorg.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForSingleDefaultGroupElement(ValidatorImpl.java:518)~[hibernate-validator-6.1.6.Final.jar:6.1.6.Final]
atorg.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup (ValidatorImpl.java:488) to [hibernate-validator-6.1.6.Final.jar:6.1.6.Final]
atorg.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup (ValidatorImpl.java:450) to [hibernate-validator-6.1.6.Final.jar:6.1.6.Final]
atorg.hibernate.validator.internal.engine.ValidatorImpl.validateInContext (ValidatorImpl.java:400) to [hibernate-validator-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.validator.internal.engine.ValidatorImpl.validate (ValidatorImpl.java:172) to [hibernate-validator-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate (BeanValidationEventListener.java:116) to [hibernate-core-5.4.23.Final.jar:5.4.23.Final]
at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreUpdate (BeanValidationEventListener.java:88) to [hibernate-core-5.4.23.Final.jar:5.4.23.Final]
at org.hibernate.action.internal.EntityUpdateAction.preUpdate(EntityUpdateAction.java:304) to [hibernate-core-5.4.23.Final.jar:5.4.23.Final]
at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:174) to [hibernate-core-5.4.23.Final.jar:5.4.23.Final]
at org.hibernate.engine.spi.ActionQueue.executeActions (ActionQueue.java:604) ~ [hibernate-core-5.4.23.Final.jar:5.4.23.Final]
at org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1 (ActionQueue.java:478) to [hibernate-core-5.4.23.Final.jar:5.4.23.Final]
at java.base/java.util.LinkedHashMap.forEach (LinkedHashMap.java:684) to [na:na]
at org.hibernate.engine.spi.ActionQueue.executeActions (ActionQueue.java:475) ~ [hibernate-core-5.4.23.Final.jar:5.4.23.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions (AbstractFlushingEventListener.java:348) to [hibernate-core-5.4.23.Final.jar:5.4.23.Final]
UserIdDuplicateCheck
package mrs.app.user;
import java.lang.announcement.Documented;
import java.lang.announcement.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
@ Documented
@Constraint(validatedBy={UserIdDuplicateCheckValidator.class})
@Target({ElementType.TYPE,ElementType.ANNOTATION_TYPE})
@ Retention (RetentionPolicy.RUNTIME)
public@interfaceUserIdDuplicateCheck{
String message() default "{mrs.app.reservation.UserIdDuplicateCheckValidator.message}";
Class <?> [ ] groups() default { };
Class <?extends Payload > [ ] payload() default { };
@Target({ElementType.METHOD,ElementType.FIELD,ElementType.ANNOTATION_TYPE,ElementType.CONSTRUCTOR,
ElementType.PARAMETER})
@ Retention (RetentionPolicy.RUNTIME)
@ Documented
public@interfaceList{
UserIdDuplicateCheck[] value();
}
}
UserIdDuplicateCheckValidator
package mrs.app.user;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import org.springframework.beans.factory.announcement.Autowired;
import ms.domain.model.User;
import mrs.domain.service.user.UserService;
public class UserId DuplicateCheckValidator
implements ConstraintValidator<UserIdDuplicateCheck,User>{
private String message;
@Autowired
UserService userService; ★★ Even if it is @Autowired, it becomes null★★
@ Override
public void initialize (UserIdDuplicateCheck constraintAnnotation) {
message=constrainAnnotation.message();
}
@ Override
public boolean isValid(User value, ConstraintValidatorContext){
String userId = value.getUserId();
Boolean blResult=userService.checkDuplicate(userId);
if(!blResult){
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(message).addPropertyNode("userId").addConstraintViolation();
}
return true;
}
}
UserService
package mrs.domain.service.user;
import org.springframework.beans.factory.announcement.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import ms.domain.model.User;
import ms.domain.repository.user.EditUserRepositoryJdbc;
import mrs.domain.repository.user.UserRepository;
@Service
public class UserService {
@Autowired
EditUserRepositoryJdbc userRepositoryJdbc;
@Autowired
UserRepository userRepository;
public void saveOrUpdate(User user, String userId)throwsDataAccessException{
System.out.println("beforeFix:"+userId);
System.out.println("fixed:"+user.getUserId());
userRepositoryJdbc.update(user,userId);
}
public boolean checkDuplicate(String userId){
if(userRepository.countByUserId(userId)!=0){
return false;
}
return true;
}
}
UserRepository
package mrs.domain.repository.user;
import javax.persistence.LockModeType;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Lock;
import org.springframework.stereotype.Repository;
import ms.domain.model.User;
@Repository
public interface UserRepository extensions JpaRepository <User, String > {
@Lock(LockModeType.PESSIMISTIC_WRITE)
User findOneForUpdateByUserId (String userId);
long countByUserId (String userId);
}
User
package mrs.domain.model;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.pattern;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.Length;
import mrs.app.user.UserIdDuplicateCheck;
// TABLE FOR STORING USER INFORMATION USING CONFERENCE ROOM RESERVATION SYSTEM
// User entity
@Entity
@Table(name="usr")
@UserIdDuplicateCheck(message="This user ID is already registered")
public class User implements Serializable {
@Id
@ NotBlank (groups=ValidGroup1.class)
@Email(groups=ValidGroup2.class)
private String userId;
@ NotBlank (groups=ValidGroup1.class)
@ Length (min=4, max=100, groups=ValidGroup2.class)
private String password;
@ NotBlank (groups=ValidGroup1.class)
private String firstName;
@ NotBlank (groups=ValidGroup1.class)
private String lastName;
/**
* Phone number
*/
@ NotBlank (groups=ValidGroup1.class)
@ Pattern(regexp="0\\d{1,4}\\d{1,4}\\d{4}", groups=ValidGroup2.class)
private String phoneNumber;
@ NotBlank (groups=ValidGroup1.class)
private String zipCode;
/**
* address
*/
@ NotBlank (groups=ValidGroup1.class)
@Size (max=200, groups=ValidGroup2.class)
private String address;
// @Enumerated (EnumType.STRING)
@ NotBlank (groups=ValidGroup1.class)
private String roleName;
public String getUserId() {
return userId;
}
public void setUserId(String userId){
this.userId = userId;
}
public String getPassword() {
return password;
}
public void setPassword (String password) {
This.password=password;
}
public String getFirstName(){
return firstName;
}
public void setFirstName(String firstName){
This.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName){
This.lastName = lastName;
}
public String getRoleName(){
return roleName;
}
public void setRoleName(String roleName){
This.roleName =roleName;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber (String phoneNumber) {
This.phoneNumber = phoneNumber;
}
public String getZipCode(){
return zipCode;
}
public void setZipCode (String zipCode) {
this.zipCode = zipCode;
}
public String getAddress() {
return address;
}
public void setAddress(String address){
this.address = address;
}
}
The second argument of self-made validation in the User class, as shown below, worked fine without any errors when I included the ValidGroup class.To be honest, I don't understand why the Validator class doesn't @Autowired unless you specify a ValidGroup class.I don't understand the specifications of Spring, so I will look into it myself, but if you know it, please let me know. m(__)m
//User entity
@Entity
@Table(name="usr")
@UserIdDuplicateCheck(message="This user ID is already registered", groups=ValidGroup2.class)
public class User implements Serializable {
What I want to do is
I think it's the second half of the , but you can do that with the following configuration:
(I think it's possible to do this with the link method.)but)
import java.util.Map;
import javax.validation.Validator;
import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.announcement.Configuration;
@Configuration
public class MyConfig {
@ Bean
public HibernatePropertiesCustomizer (final Validator validator) {
return new HibernatePropertiesCustomizer(){
@ Override
public void customize (Map<String,Object>hibernateProperties) {
hibernateProperties.put("javax.persistence.validation.factory", validator);
}
};
}
}
The ValidationAutoConfiguration
when added to the relationship (so you should not need to configure it manually).
© 2024 OneMinuteCode. All rights reserved.