JPA Buddy
announcement - icon

JPA is huge! It covers nearly every aspect of communication between relational databases and the Java application and is deeply integrated into all major frameworks.

If you're using IntelliJ, JPA Buddy is super helpful. The plugin gently guides you through the subtleties of the most popular JPA implementations, visually reminds you of JPA features, generates code that follows best practices, and integrates intelligent inspections to improve your existing persistence code.

More concretely, it provides powerful tooling to generate Spring Data JPA repositories and methods, Flyway Versioned Migrations, Liquibase Differential Changelogs, DDL and SQL statements, DTO objects, and MapStruct interfaces.

Oh, and it actually generates JPA entities from an existing database and gradually update the data model as the database evolves! Yeah.

>> Become a lot more productive with JPA Buddy

Persistence top

Get started with Spring Data JPA through the reference Learn Spring Data JPA course:


1. Introduction

Spring Data JPA offers many features to use JPA in an application. Among those features, there's the standardization of table and column names in both DDL and DML queries.

In this short tutorial, we're going to see how to configure this default naming convention.

2. Default Naming Convention

First of all, let's see what Spring's default naming convention regarding table and column names.

Let's imagine we have a Person entity:

public class Person {
    private Long id;
    private String firstName;
    private String lastName;

We have a few names here that have to be mapped to the database. Well, Spring uses lower snake case by default, which means it uses only lower case letters and separates words with underscores. Therefore, the table creation query for the Person entity would be:

create table person (id bigint not null, first_name varchar(255), last_name varchar(255), primary key (id));

And a selection query returning all first names would be:

select first_name from person;

To do that, Spring implemented its version of the Hibernate's PhysicalNamingStrategy: SpringPhysicalNamingStrategy.

3. RDMS Case-Sensitivity

Before going into the details of how to create our custom naming convention, let's talk a bit about how the RDMS is managing the case of the identifiers.

There are two scenarios to consider: the RDMS is case-sensitive, or it is not.

In the first situation, the RDMS will strictly match identifiers that have the same case. Therefore, in our example, the following query would work:

select first_name from person;

While this one will throw an error and not even return a result:

select FIRST_NAME from PERSON;

On the other hand, for an RDMS that is case-insensitive, both queries would have worked.

What would we do to force the RDMS to match identifiers regarding their case as well? We can use quoted identifiers (for example, “person”).

By using quotes around our identifiers, we tell the database it should also match the case when comparing those identifiers with table and column names. So, still using our example, the following query would work:

select "first_name" from "person";

While this one wouldn't:

select "first_name" from "PERSON";

That's in theory though, because each RDMS manages quoted identifiers in its own way, so mileage varies.

4. Custom Naming Convention

Now, let's implement our own naming convention.

Imagine we can't use the Spring lower snake case strategy, but we need to use upper snake case. Then, we'd need to provide an implementation of PhysicalNamingStrategy.

As we're going to keep to snake case, the fastest option is to inherit from the SpringPhysicalNamingStrategy and turn identifiers to upper case:

public class UpperCaseNamingStrategy extends SpringPhysicalNamingStrategy {
    protected Identifier getIdentifier(String name, boolean quoted, JdbcEnvironment jdbcEnvironment) {
        return new Identifier(name.toUpperCase(), quoted);

We're just overriding the getIdentifier() method, which is in charge of turning the identifiers to lower case in the super-class. Here we're using it to convert them to upper case.

Once we've written our implementation, we must register it so that Hibernate knows to use it. Using Spring, this is done by setting the spring.jpa.hibernate.naming.physical-strategy property in our


Now, our queries are using upper case identifiers:

create table PERSON (ID bigint not null, FIRST_NAME varchar(255), LAST_NAME varchar(255), primary key (ID));

select FIRST_NAME from PERSON;

Let's say that we want to use quoted identifiers so that the RDMS is forced to match the case. Then we would have to use true as the quoted argument of the Identifier() constructor:

protected Identifier getIdentifier(String name, boolean quoted, JdbcEnvironment jdbcEnvironment) {
    return new Identifier(name.toUpperCase(), true);

After what our queries would present quoted identifiers:

create table "PERSON" ("ID" bigint not null, "FIRST_NAME" varchar(255), "LAST_NAME" varchar(255), primary key ("ID"));

select "FIRST_NAME" from "PERSON";

5. Conclusion

In this short article, we talked about the possibilities of implementing a custom naming strategy using Spring Data JPA and how the RDMS will handle our DDL and DML statements regarding its internal configuration.

As usual, the full code for this article can be found over on GitHub.

Persistence bottom
Get started with Spring Data JPA through the reference Learn Spring Data JPA course: >> CHECK OUT THE COURSE
Persistence footer banner
Comments are closed on this article!