Spring Boot+MySQL注册报错:Data too long for column 'password'
问题:Spring Boot + MySQL 用户注册密码哈希后报错 Data truncation: Data too long for column 'password'
未添加密码哈希时注册功能正常,使用BCrypt加密密码后,抛出数据截断错误,提示密码列长度不足。
错误日志
com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Data too long for column 'password' at row 1 at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:104) ~[mysql-connector-j-8.0.31.jar:8.0.31] at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:916) ~[mysql-connector-j-8.0.31.jar:8.0.31] at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1061) ~[mysql-connector-j-8.0.31.jar:8.0.31] at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1009) ~[mysql-connector-j-8.0.31.jar:8.0.31] at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1320) ~[mysql-connector-j-8.0.31.jar:8.0.31] at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:994) ~[mysql-connector-j-8.0.31.jar:8.0.31] at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61) ~[HikariCP-4.0.3.jar:na] at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java) ~[HikariCP-4.0.3.jar:na] at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final] at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:46) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final] at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3375) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final] at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3908) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final] at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:107) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final] at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final] at org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:478) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final] at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) ~[na:1.8.0_202] at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final] at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:344) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final] at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final] at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final] at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1407) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final] at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:489) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final] at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3303) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final] at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2438) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final] at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:449) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final] at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:183) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final] at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:40) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final] at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:281) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final] at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final] at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:562) ~[spring-orm-5.3.23.jar:5.3.23] at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:743) ~[spring-tx-5.3.23.jar:5.3.23] at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711) ~[spring-tx-5.3.23.jar:5.3.23]
相关代码
EmployeeIMPL.java
@Service public class EmployeeIMPL implements EmployeeService { @Autowired private EmployeeRepo employeeRepo; PasswordEncoder passwordEncoder; @Override public String addEmployee(EmployeeDTO employeeDTO) { this.passwordEncoder = new BCryptPasswordEncoder(); Employee employee = new Employee( employeeDTO.getEmployeeid(), employeeDTO.getEmployeename(), employeeDTO.getEmail(), this.passwordEncoder.encode(employeeDTO.getPassword()) ); employeeRepo.save(employee); return employee.getEmployeename(); } }
Employee 实体类
@Id @Column(name="employee_id", length = 45) @GeneratedValue(strategy = GenerationType.AUTO) private int employeeid; @Column(name="employee_name", length = 255) private String employeename; @Column(name="email", length = 255) private String email; @Column(name="password", length = 20) private String password;
解决方案
问题根源:BCrypt加密后的密码固定为60位字符串,而实体类和数据库密码列仅设置了20位长度,导致插入时数据截断。
解决步骤:
- 修改实体类密码字段长度:将
@Column(name="password", length = 20)改为@Column(name="password", length = 60),确保能容纳加密后的密码:@Column(name="password", length = 60) private String password; - 同步更新数据库表结构:手动修改MySQL中
employee表的password列长度,执行SQL:ALTER TABLE employee MODIFY COLUMN password VARCHAR(60); - 优化密码编码器注入:避免在方法内重复创建编码器实例,通过Spring注入更规范:
新增配置类:
修改EmployeeIMPL注入编码器:@Configuration public class SecurityConfig { @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }@Service public class EmployeeIMPL implements EmployeeService { @Autowired private EmployeeRepo employeeRepo; @Autowired private PasswordEncoder passwordEncoder; @Override public String addEmployee(EmployeeDTO employeeDTO) { Employee employee = new Employee( employeeDTO.getEmployeeid(), employeeDTO.getEmployeename(), employeeDTO.getEmail(), passwordEncoder.encode(employeeDTO.getPassword()) ); employeeRepo.save(employee); return employee.getEmployeename(); } }
内容的提问来源于stack exchange,提问作者abi jega
相关产品推荐
相关产品推荐

