Keywords: Spring Boot | JPA | Hibernate Naming Strategy
Abstract: This technical article provides an in-depth analysis of why the @Column annotation's name attribute is ignored in Spring Boot applications using JPA. It examines the naming strategy changes in Hibernate 5+, detailing how the default SpringNamingStrategy converts camelCase to snake_case, overriding explicitly specified column names. The article presents two effective solutions: configuring the physical naming strategy to PhysicalNamingStrategyStandardImpl for direct annotation name usage, and employing EJB3NamingStrategy to avoid naming transformations. It also explores the impact of SQL Server dialects on naming behavior and demonstrates different configuration outcomes through comprehensive code examples.
Problem Background and Phenomenon Analysis
When integrating JPA with Spring Boot applications, developers often encounter situations where the @Column(name="TestName") annotation is ignored. Despite explicitly specifying the column name in the entity class, the generated SQL statements use snake_case names derived from field names (e.g., test_name). The root cause of this phenomenon lies in Hibernate's naming strategy mechanism.
Hibernate Naming Strategy Mechanism Analysis
Hibernate 5+ introduced a new naming strategy architecture that divides the naming process into two phases: implicit naming strategy and physical naming strategy. The implicit naming strategy generates logical names from the object model (such as entity classes and fields), while the physical naming strategy converts these logical names into actual database identifiers.
Spring Boot defaults to using SpringPhysicalNamingStrategy, which extends Hibernate's PhysicalNamingStrategyStandardImpl but performs additional naming transformations. Specifically, it converts camelCase identifiers to snake_case:
// Default behavior example
@Column(name="TestName")
private String testName;
// Actual generated column name: test_nameThis transformation occurs during the physical naming phase, thereby overriding the name specified in the @Column annotation. Even if the annotation explicitly sets name="TestName", the physical naming strategy still converts it to test_name.
Solution 1: Configuring Physical Naming Strategy
The most direct solution is to configure the physical naming strategy to PhysicalNamingStrategyStandardImpl, which directly uses the name specified in the annotation without any transformation:
# application.properties configuration
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImplAfter configuration, Hibernate will strictly adhere to the name attribute of the @Column annotation:
@Entity
public class User {
@Column(name="TestName")
private String testName;
// Generated column name: TestName
}This approach ensures complete respect for the annotation name and is suitable for scenarios requiring precise control over database column names.
Solution 2: Using Legacy Naming Strategies
Another approach is to configure the implicit naming strategy to ImplicitNamingStrategyLegacyJpaImpl, combined with the physical naming strategy configuration:
# application.properties configuration
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImplThis combination restores the naming behavior of Hibernate 4, where the implicit naming strategy generates logical names based on JPA specifications, and the physical naming strategy uses these names directly. For the example field:
@Column(name="TestName")
private String testName;
// Logical name: TestName (from annotation)
// Physical name: TestName (no transformation)This method maintains compatibility with JPA specifications while ensuring naming consistency.
Impact of Database Dialects
It is important to note that database dialects typically do not directly affect naming strategies. The warning Unknown Microsoft SQL Server major version [12] using SQL Server 2000 dialect mentioned in the problem description indicates that Hibernate failed to correctly identify the SQL Server 2014 version, but this has no direct impact on naming strategies. Dialects primarily influence SQL statement generation (such as data type mapping and specific syntax), while naming strategies operate independently of dialects.
Best Practices and Considerations
When selecting naming strategies, consider the specific requirements of the project:
- If strict control over database column names is needed, recommend using
PhysicalNamingStrategyStandardImpl - If the project requires naming compatibility with legacy systems, consider the full legacy strategy configuration
- For new projects, it is advisable to explicitly configure naming strategies to avoid reliance on default behavior changes
Additionally, teams should unify naming conventions to ensure consistency between entity class design and database schema. Through explicit configuration, naming behavior changes due to Hibernate version upgrades can be prevented.