@ UserService injected in Autowired becomes null

Asked 2 years ago, Updated 2 years ago, 115 views

What do you want to do

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

Problems/Error Messages you are experiencing

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]

Source Codes Affected

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;
    }

}

Tried

https://medium.com/ @ssscripting/getting-autowired-fields-to-work-constructor5

Based on the above site, we created a validationConfig class and placed it in the same package as the application class. We configured the , but it remained null.(To be honest, I don't really understand what this validationConfig class is doing)
After that, I tried to google it, but it didn't solve the problem, so I'll ask you a question here.
Thank you for your cooperation.

java spring-boot

2022-09-29 22:09

2 Answers

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 {


2022-09-29 22:09

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).


2022-09-29 22:09

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.