Spring Boot实体类字段无法同步更新至数据库问题求助
问题描述
开发Spring Boot应用时遇到实体类字段无法同步至数据库的问题:表名可正常更新,但列名、@Column注解的nullable属性、@Id的自动生成策略均未生效,具体表现为:
- 列名被自动转为下划线格式(如
firstName变为first_name) - 字段未设置非空约束
- 手动插入数据时必须指定
id值
已尝试刷新MySQL schema、重建数据库、重新构建Maven项目,但问题仍未解决。
User实体类代码
package com.helpinghand.HelpingHand.Backend.Model; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import javax.persistence.*; import java.time.LocalDateTime; @Entity @Table(name = "User") public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; @Column(name = "firstName", nullable = false) private String firstName; @Column(nullable = false) private String lastName; @Column(nullable = false) private String phoneNumber; @Column(nullable = false) private String streetAddress; @Column(nullable = false) private String city; @Column(nullable = false) private String state; @Column(nullable = false) private String zip; @Column(nullable = false, unique = true) private String email; @Column(nullable = false) private boolean isAdmin; @Column(nullable = false) private String password; @Column(nullable = false) private LocalDateTime createdDate; public User() { } public User(String firstName, String lastName, String phoneNumber, String streetAddress, String city, String state, String zip, String email, boolean isAdmin, LocalDateTime createDate, String password) { this.firstName = firstName; this.lastName = lastName; this.phoneNumber = phoneNumber; this.streetAddress = streetAddress; this.city = city; this.state = state; this.zip = zip; this.email = email; this.isAdmin = isAdmin; this.createdDate = createDate; // this.password = password; setPassword(password); // Set the hashed password } public long getId() { return id; } public void setId(long id) { this.id = id; } 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 getPhoneNumber() { return phoneNumber; } public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } public String getStreetAddress() { return streetAddress; } public void setStreetAddress(String streetAddress) { this.streetAddress = streetAddress; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getState() { return state; } public void setState(String state) { this.state = state; } public String getZip() { return zip; } public void setZip(String zip) { this.zip = zip; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public boolean isAdmin() { return isAdmin; } public void setAdmin(boolean admin) { isAdmin = admin; } public LocalDateTime getCreatedDate() { return createdDate; } public void setCreatedDate(LocalDateTime createDate) { this.createdDate = createDate; } public String getPassword() { return password; } // public void setPassword(String password) { // this.password = password; // } public void setPassword(String password) { // TODO: Perform password hashing here this.password = hashPassword(password); } private String hashPassword(String password) { BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); return passwordEncoder.encode(password); } }
application.properties配置
server.port = 8080 spring.datasource.url=jdbc:mysql://localhost:3306/helpinghand spring.datasource.username=root spring.datasource.password= spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect #spring.jpa.hibernate.ddl-auto=none spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true #server.port=8080 # #spring.datasource.url=jdbc:mysql://localhost:3306/helpinghand #spring.datasource.username=root #spring.datasource.password= #spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver #spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect #spring.jpa.hibernate.ddl-auto=create-drop #spring.jpa.show-sql=true
解决方案
1. 修复列名自动转下划线问题
Hibernate默认的物理命名策略会把实体类的驼峰字段转成下划线格式,要保留@Column指定的列名,在application.properties中添加:
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
该配置会让Hibernate严格使用你在@Column(name="xxx")里指定的列名,不再自动转换格式。
2. 修复nullable属性不生效问题
- 若之前已创建过表,
update模式不会修改已有列的约束(仅新增列或表)。可临时将spring.jpa.hibernate.ddl-auto改成create-drop,重启应用让Hibernate重建表,之后再改回update;或者手动删除数据库中的User表,用update模式重新生成。 - 确保实体类中
@Column(nullable=false)的字段未被其他全局配置覆盖。
3. 修复@Id自动生成策略不生效问题
GenerationType.AUTO在MySQL环境下可能无法正确适配自增策略,直接修改@GeneratedValue的策略:
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id;
此配置会让Hibernate使用MySQL的自增主键机制,插入数据时无需手动指定id,数据库会自动生成。若之前表已存在,需手动将id列改成AUTO_INCREMENT类型,或重建表。
内容的提问来源于stack exchange,提问作者deckard2020
相关产品推荐
相关产品推荐

