#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:
Я добавлял запись администратора, напрямую жестко кодируя ее, что вызвало эту проблему(я не обновил там новые параметры).