Получение исключения DataIntegrityViolationException при получении регистрационной формы

#mysql #spring-boot #hibernate #spring-security

Вопрос:

Я начал получать ниже упомянутое исключение после добавления поля pincode(zipcode) при регистрации формы. Я не понимаю, где что-то пошло не так. Я знал, что проблема связана с пустым пинкодом, но не смог найти решение/подсказку для ее решения.

 org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:276)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:233)
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:566)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:743)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:654)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:407)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692)
    at org.brahmakumaris.journeyfood.SetupDataLoader$EnhancerBySpringCGLIB$f05400c.onApplicationEvent(<generated>)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:421)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:378)
    at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:938)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:782)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:774)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:339)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1340)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1329)
    at org.brahmakumaris.journeyfood.JourneyfoodApplication.main(JourneyfoodApplication.java:12)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
    at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:59)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:200)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3297)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3824)
    at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:107)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604)
    at org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:478)
    at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:723)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475)
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:345)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40)
    at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:93)
    at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1362)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:453)
    at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3212)
    at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2380)
    at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:447)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:183)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:40)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:281)
    at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101)
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:562)
    ... 29 common frames omitted
Caused by: java.sql.SQLIntegrityConstraintViolationException: Column 'pincode' cannot be null
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:117)
    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1092)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1040)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1348)
 

AuthenticationController.java

 @Controller
public class AutheticationController {
    
    private Logger LOGGER = LoggerFactory.getLogger(AutheticationController.class);

    @Autowired
    private DefaultUserService userService;
    
    @GetMapping("/register")
    public String register(final Model model) {
        model.addAttribute("user", new UserSignUpFormData());
        return "register";
    }
    
    @PostMapping("/register")//Post operation
    public ModelAndView register(@Valid @ModelAttribute("user")UserSignUpFormData user, BindingResult result,HttpServletRequest request) {
        ModelAndView mav = new ModelAndView("register", "user", user);
        LOGGER.info("AutheticationController register method - Entered");
        if (result.hasErrors()) {
            return mav;
        }
        else {
            try {
                userService.register(user,DefaultUserService.getSiteURL(request));
            }catch (Exception e){
                if(e instanceof UserAlreadyExistException)  mav.addObject("message", "An account with this email already exists.");
                LOGGER.error(e.getMessage());
                return mav;
            }
          LOGGER.info("AutheticationController register method Exit: User => " user);   
          return new ModelAndView("signup-success", "user", user);
        }
    }
}
 

UserSignUpFormData.java

 public class UserSignUpFormData {
    @NotBlank(message="Name Of Center is mandatory")
    private String nameOfCenter;
    @NotBlank(message="Name Of Guide/Teacher is mandatory")
    private String nameOfGuide;
    @NotBlank(message="Contact No is is mandatory")
    @ContactNumberConstraint(message = "Invalid Contact number")
    private String contactNoOfGuide;
    @NotBlank(message="Zone name is mandatory")
    private String zoneName;
    @NotBlank(message="Subzone/City name is mandatory")
    private String subZone;
    @NotBlank(message="Pincode/Zipcode is mandatory")
    private long pincode;
    @NotBlank(message="Email is mandatory")
    private String email;
    @NotBlank(message="Password is mandatory")
    private String password;
    
    public UserSignUpFormData() {
        super();
    }

    public UserSignUpFormData(@NotBlank(message = "Email is mandatory") String email) {
        super();
        this.email = email;
    }
    //getters and setters
}
 

UserEntity.java

 @Entity
@Table(name="users")
public class UserEntity {
    @Id
    @Column(unique = true, nullable = false)
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "users_roles", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"))
    private Collection<Role> roles;
    
    @Column(nullable = false, length = 100)
    private String nameOfCenter;

    @Column(nullable = false, length = 100)
    private String nameOfGuide;
    
    @Column(nullable = false, length = 18)
    private String contactNoOfGuide;
    
    @Column(nullable = false, unique = true, length = 70)
    private String email;
    
    @Column(nullable = false, unique = true, length = 70)
    private String zone;
    
    @Column(nullable = false, unique = true, length = 70)
    private String subZone;
    
    @Column(nullable = false, unique = true, length = 10)
    private Long pincode;
    
    @Column(nullable = false, length = 150)
    private String password;
    
    @Column(nullable = false)
    @Type(type = "org.hibernate.type.NumericBooleanType")
    private boolean enabled;//whether account is verified using email or not
    
    public UserEntity(long id, Collection<Role> roles, String nameOfCenter, String nameOfGuide, String contactNoOfGuide, String email, String zone, String subZone, Long pincode, String password, boolean enabled) {
        super();
        this.id = id;
        this.roles = roles;
        this.nameOfCenter = nameOfCenter;
        this.nameOfGuide = nameOfGuide;
        this.contactNoOfGuide = contactNoOfGuide;
        this.email = email;
        this.zone = zone;
        this.subZone = subZone;
        this.pincode = pincode;
        this.password = password;
        this.enabled = enabled;
    }

    public UserEntity(String email) {
        super();
        this.email = email;
    }
    
    public UserEntity() {
        super();
    }
    //getters and setters
}
 

DefaultUserService.java

 @Service("UserService")
@Transactional
public class DefaultUserService implements UserService {
    private static Logger LOGGER = LoggerFactory.getLogger(DefaultUserService.class);
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private RoleRepository roleRepository;
    
    @Autowired
    private BCryptPasswordEncoder bcryptEncoder;
        
    @Override
    public UserEntity register(UserSignUpFormData user, String link) throws UserAlreadyExistException, MessagingException, UnsupportedEncodingException{
        LOGGER.info("DefaultUserService - register() Entered -User=> " user);
        if(checkIfUserExist(user.getEmail())) {
            LOGGER.error("-------------------------------------------------------------------User already exists");
            throw new  UserAlreadyExistException("User already exists for this email :" user.getEmail());
        }
        UserEntity userEntity = new UserEntity();
        userEntity.setContactNoOfGuide(user.getContactNoOfGuide());
        userEntity.setEmail(user.getEmail());
        userEntity.setNameOfCenter(user.getNameOfCenter());
        userEntity.setNameOfGuide(user.getNameOfGuide());
        userEntity.setZone(user.getZoneName());
        userEntity.setSubZone(user.getSubZone());
        userEntity.setPincode(user.getPincode());
        final Role userRole =  createRoleIfNotFound("ROLE_USER", assignPrivilege(userEntity));
        encodePassword(userEntity, user);//Encoding and setting password
        userEntity.setRoles(Arrays.asList(userRole));
        sendEmailVerificationMail(userEntity, link);
        LOGGER.info("DefaultUserService - register User Exit => " user);
        return userRepository.save(userEntity);
    }
.........
}   
 

register.html

 <form th:action="@{/register}" th:object="${user}" method="post" style="max-width: 600px; margin: 0 auto;">
            <div class="alert alert-danger" role="alert" th:if="${#fields.hasAnyErrors()}">
                <ul>
                    <li th:each="err : ${#fields.allErrors()}" th:text="${err}" />
                </ul>
            </div>
            <div class="alert alert-danger" th:text="${message}" th:unless="${message==null}" role="alert">
            </div>
            <div class="m-3">
                <div class="form-group row">
                    <label class="col-4 col-form-label">Name of Center: </label>
                    <div class="col-8">
                        <input type="text" th:field="*{nameOfCenter}" class="form-control" required />
                        <div class="alert alert-danger" role="alert" th:if="${#fields.hasErrors('nameOfCenter')}" th:errors="*{nameOfCenter}"></div>
                    </div>
                </div>
                 
                <div class="form-group row">
                    <label class="col-4 col-form-label">Name of Guide: </label>
                    <div class="col-8">
                        <input type="text" th:field="*{nameOfGuide}" class="form-control" required minlength="2" maxlength="20"/>
                        <div class="alert alert-danger" role="alert" th:if="${#fields.hasErrors('nameOfGuide')}" th:errors="*{nameOfGuide}"></div>
                    </div>
                </div>

                <div class="form-group row">
                    <label class="col-4 col-form-label">Zone Name : </label>
                    <div class="col-8">
                        <input type="text" th:field="*{zoneName}" class="form-control" required />
                        <div class="alert alert-danger" role="alert" th:if="${#fields.hasErrors('zoneName')}" th:errors="*{zoneName}"></div>
                    </div>
                </div>

                <div class="form-group row">
                    <label class="col-4 col-form-label">City/Sub-Zone name: </label>
                    <div class="col-8">
                        <input type="text" th:field="*{subZone}" class="form-control" required />
                        <div class="alert alert-danger" role="alert" th:if="${#fields.hasErrors('subZone')}" th:errors="*{subZone}"></div>
                    </div>
                </div>

                <div class="form-group row">
                    <label class="col-4 col-form-label">Pincode/Zipcode : </label>
                    <div class="col-8">
                        <input type="number" th:field="*{pincode}" class="form-control" value="0" required />
                        <div class="alert alert-danger" role="alert" th:if="${#fields.hasErrors('pincode')}" th:errors="*{pincode}"></div>
                    </div>
                </div>              

                <div class="form-group row">
                    <label class="col-4 col-form-label">E-mail : </label>
                    <div class="col-8">
                        <input type="email" th:field="*{email}" class="form-control" required />
                        <div class="alert alert-danger" role="alert" th:if="${#fields.hasErrors('email')}" th:errors="*{email}"></div>
                    </div>
                </div>
                
                <div class="form-group row">
                    <label class="col-4 col-form-label">Password: </label>
                    <div class="col-8">
                        <input type="password" th:field="*{password}" class="form-control" required minlength="6" maxlength="10"/>
                        <div class="alert alert-danger" role="alert" th:if="${#fields.hasErrors('password')}" th:errors="*{password}"></div>
                    </div>
                </div>
                
                 <div class="form-group row">
                    <label class="col-4 col-form-label">Mobile no of Guide: </label>
                    <div class="col-8">
                        <input type="text" th:field="*{contactNoOfGuide}" class="form-control" required />
                        <div class="alert alert-danger" role="alert" th:if="${#fields.hasErrors('contactNoOfGuide')}" th:errors="*{contactNoOfGuide}"></div>
                    </div>
                </div>
    
                <div>
                    <button type="submit" class="btn btn-primary">Sign Up</button>
                </div>
            </div>
        </form>
 

Пожалуйста, помогите мне в решении этой проблемы.

Ответ №1:

Я добавлял запись администратора, напрямую жестко кодируя ее, что вызвало эту проблему(я не обновил там новые параметры).