DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • Best Performance Practices for Hibernate 5 and Spring Boot 2 (Part 4)
  • Best Performance Practices for Hibernate 5 and Spring Boot 2 (Part 1)
  • Querydsl vs. JPA Criteria, Part 6: Upgrade Guide To Spring Boot 3.2 for Spring Data JPA and Querydsl Project
  • Upgrade Guide To Spring Boot 3.0 for Spring Data JPA and Querydsl

Trending

  • Chaos Engineering for Microservices
  • AI-Driven Test Automation Techniques for Multimodal Systems
  • Building Resilient Identity Systems: Lessons from Securing Billions of Authentication Requests
  • Unlocking the Benefits of a Private API in AWS API Gateway
  1. DZone
  2. Coding
  3. Frameworks
  4. Hibernate Naming Strategies: JPA Specification vs Spring Boot Opinionation

Hibernate Naming Strategies: JPA Specification vs Spring Boot Opinionation

In this article, look at Hibernate naming strategies.

By 
Aleksey Stukalov user avatar
Aleksey Stukalov
·
Andrey Oganesyan user avatar
Andrey Oganesyan
·
Mar. 23, 21 · Opinion
Likes (20)
Comment
Save
Tweet
Share
4.7K Views

Join the DZone community and get the full member experience.

Join For Free

Each time we inject a dependency into our project, we sign a contract, which often has lots of hidden things "written in the fine print". In this article, we will take a look at something you could miss when signing a tripartite contract between you, Hibernate, and Spring Boot. We will talk about naming strategies.

Defaults in JPA Naming

The ultimate rule about defaults: they must be intuitive. Let's check if this rule applies to a standard Spring Boot application with default configuration using Hibernate as a JPA implementation. Imagine you have an entity "PetType". Let's guess what table name in the database it is associated with.

First example:

Java
 




x


 
1
@Entity 
2
public class PetType { 
3
  // fields omitted 
4
} 



To me, the most intuitive table name would be the class name, which is PetType. Running a test against PostgreSQL we find out that the associated table name is actually pet_type.
Let's set the name explicitly using@Table:

Java
 




xxxxxxxxxx
1


 
1
@Entity 
2
@Table(name = "PetType")
3
public class PetType { 
4
  // fields omitted 
5
} 



This time we expect to see PetType for sure, but if we run the test... pet_type again!

Well, let's wrap the table name in quotes. This should keep not only the defined name but also the case.

Java
 




xxxxxxxxxx
1


 
1
@Entity 
2
@Table(name = "\"PetType\"") 
3
public class PetType {
4
  // fields omitted 
5
} 



Again, our expectations were wrong, and we see "pet_type", but now in quotes!

Hibernate Naming Strategies

Googling "JPA entity default table name" you'll most probably stumble onto the following result: The JPA default table name is the name of the class (minus the package) with the first letter capitalized. Each attribute of the class will be stored in a column in the table. It is exactly what we expected to see in the first example, isn't it? Obviously, something breaks the standard.

Let's dive deeper into Hibernate. According to the documentation, there are two interfaces responsible for naming your tables, columns etc. in Hibernate: ImplicitNamingStrategy and PhysicalNamingStrategy.

ImplicitNamingStrategy is in charge of naming all objects that were not explicitly named by a developer: e.g. entity name, table name, column name, index, FK etc. The resulting name is called the logical name, it is used internally by Hibernate to identify an object. It is not the name that gets put into the DB.

PhysicalNamingStrategy provides the actual physical name used in the DB based on the logical JPA object name. Effectively, this means that using Hibernate you cannot specify database object names directly, but only logical ones. To have a better understanding of what's happening under the hood, see the diagram below.

PhysicalNamingStrategy diagram

Hibernate default implementations of these interfaces are ImplicitNamingStrategyJpaCompliantImpl and PhysicalNamingStrategyStandardImpl. The former generates logical names in accordance with the JPA specification, and the latter uses them as physical names without any modifications. This is best described in the documentation:

JPA defines inherent rules about implicit logical name determination. If JPA provider portability is a major concern, or if you really just like the JPA-defined implicit naming rules, be sure to stick with ImplicitNamingStrategyJpaCompliantImpl (the default).
Also, JPA defines no separation between logical and physical name. Following the JPA specification, the logical name is the physical name. If JPA provider portability is important, applications should prefer not to specify a PhysicalNamingStrategy.

However, our application shows different behaviour. And this is why. Spring Boot overrides Hibernate default implementations for both interfaces and uses SpringImplicitNamingStrategy and SpringPhysicalNamingStrategy instead.

Effectively, SpringImplicitNamingStrategy copies the behaviour of ImplicitNamingStrategyJpaCompliantImpl with only a minor difference in join table naming. So, it must be SpringPhysicalNamingStrategy that produces the results we've seen. The documentation states the following:

By default, Spring Boot configures the physical naming strategy with SpringPhysicalNamingStrategy. This implementation provides the same table structure as Hibernate 4: all dots are replaced by underscores and camel casing is replaced by underscores as well. Additionally, by default, all table names are generated in lower case. For example, a TelephoneNumber entity is mapped to the telephone_number table.

Basically, it always transforms camelCase and PascalCase to snake_case. In fact, using it isn't possible to work with non_snake_case at all. Personally, I would never use camelCase or PascalCase for naming database objects, but there are DB admins who would. If your Spring Boot application deals with a third-party database where at least one table or column is defined in a pascal or camel case, the default Spring Boot setup will not work for you. So, make sure the used physical naming strategy supports the given database naming convention. Learn how to change the default naming strategy in this article or, if required, learn how to provide your own implementation here.

So, Hibernate complies with the JPA spec and Spring Boot doesn't. This may look like a bug, but Spring Boot claims to be an opinionated framework. In other words, it has the full right to apply its own opinion over all standards and specs of the technology used under the hood. For a developer this means the following:

  • "Opinionation" may override any specification. In other words, specs and standards state how it should be, while the used implementation defines what it actually is.
  • If something even works by default, you should always learn what this default is and how exactly it works.
  • Defaults may change with a library version upgrade, which can lead to unpredictable side effects.

Conclusion

The magic of default configurations may work until you hit some unexpected behaviour. To avoid such risk, you may prefer explicit definition to implicit use of defaults. So, in our case the recommendation would be:

  1. Always name your JPA objects explicitly, so that no Implicit Naming Strategy affects your code
  2. Use the snake_case for columns, tables, indexes and other JPA objects names in order to avoid their transformation by any implementation of the Physical Naming Strategy
  3. In case snake_case doesn't work for you (e.g. using a legacy database), set Physical Naming Strategy to PhysicalNamingStrategyStandardImpl

Explicit naming of JPA objects will also prevent database schema from unwanted changes in case of an entity class or a field name refactoring.

You may notice that solving potential problems in runtime we simply transfer responsibilities to developers by introducing naming conventions. Now we need to make sure that all developers follow the same rules. This can be automated by shifting these responsibilities further to development tools.


So, if you use IntelliJ IDEA, you may try JPA Buddy — a plugin intended to help developers with JPA, Hibernate, Spring Data JPA, Liquibase, and other related technology. JPA Buddy enables a team to set up agreed code conventions and apply them for newly generated JPA entities.

Spring Framework Spring Boot Database Hibernate

Published at DZone with permission of Aleksey Stukalov, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Best Performance Practices for Hibernate 5 and Spring Boot 2 (Part 4)
  • Best Performance Practices for Hibernate 5 and Spring Boot 2 (Part 1)
  • Querydsl vs. JPA Criteria, Part 6: Upgrade Guide To Spring Boot 3.2 for Spring Data JPA and Querydsl Project
  • Upgrade Guide To Spring Boot 3.0 for Spring Data JPA and Querydsl

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!