Introduction
When using PostgreSQL with JPA, uppercase identifiers can become a source of subtle bugs. PostgreSQL lowercases unquoted identifiers, so entity mappings must be explicit when your schema uses uppercase table or column names.
1. Use Explicit @Table and @Column Names
Map fields to exact identifiers in your schema:
@Entity
@Table(name = "\"MY_TABLE\"")
public class MyEntity {
@Id
@Column(name = "\"ID\"")
private Long id;
@Column(name = "\"FIRST_NAME\"")
private String firstName;
@Column(name = "\"LAST_NAME\"")
private String lastName;
}
The explicit quoting preserves case sensitivity in PostgreSQL.
2. Configure Hibernate Physical Naming Strategy
If naming strategy transforms identifiers, mappings may still break. Use PhysicalNamingStrategyStandardImpl to preserve names exactly as declared in annotations.
spring:
jpa:
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
3. Match Migrations to the Same Naming Rules
Your migration scripts must also define quoted uppercase names:
CREATE TABLE "MY_TABLE" (
"ID" SERIAL PRIMARY KEY,
"FIRST_NAME" VARCHAR(50),
"LAST_NAME" VARCHAR(50),
"CREATED_AT" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
If entities and migrations do not use the same conventions, runtime mapping errors are very likely.
Common Pitfall
A frequent mistake is quoting names in entities but not in migration scripts, or vice versa. Keep both layers aligned from day one.
Conclusion
To make JPA work reliably with uppercase PostgreSQL identifiers:
- Use explicit quoted names in
@Tableand@Column. - Disable automatic case transformations with a compatible physical naming strategy.
- Keep Flyway or Liquibase migrations consistent with the same naming approach.
This prevents hard-to-debug mapping issues and keeps your persistence layer predictable.