[[naming]]
=== Naming strategies
:sourcedir: ../../../../../test/java/org/hibernate/userguide/naming

Part of the mapping of an object model to the relational database is
mapping names from the object model to the corresponding database names.
Hibernate looks at this as 2-stage process:

* The first stage is determining a proper logical name from the domain model mapping.  A
	logical name can be either explicitly specified by the user (e.g., using `@Column` or
	`@Table`) or it can be implicitly determined by Hibernate through an
	<<ImplicitNamingStrategy>> contract.
* Second is the resolving of this logical name to a physical name which is defined
	by the <<PhysicalNamingStrategy>> contract.


[NOTE]
.Historical NamingStrategy contract
====
Historically Hibernate defined just a single `org.hibernate.cfg.NamingStrategy`.  That singular
NamingStrategy contract actually combined the separate concerns that are now modeled individually
as ImplicitNamingStrategy and PhysicalNamingStrategy.

Also, the NamingStrategy contract was often not flexible enough to properly apply a given naming
"rule", either because the API lacked the information to decide or because the API was honestly
not well defined as it grew.

Due to these limitation, `org.hibernate.cfg.NamingStrategy` has been deprecated
in favor of ImplicitNamingStrategy and PhysicalNamingStrategy.
====

At the core, the idea behind each naming strategy is to minimize the amount of
repetitive information a developer must provide for mapping a domain model.


[NOTE]
.JPA Compatibility
====
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.
====


[[ImplicitNamingStrategy]]
==== ImplicitNamingStrategy

When an entity does not explicitly name the database table that it maps to, we need
to implicitly determine that table name.  Or when a particular attribute does not explicitly name
the database column that it maps to, we need to implicitly determine that column name.  There are
examples of the role of the `org.hibernate.boot.model.naming.ImplicitNamingStrategy` contract to
determine a logical name when the mapping did not provide an explicit name.

image:images/domain/naming/implicit_naming_strategy_diagram.svg[Implicit Naming Strategy Diagram]

Hibernate defines multiple ImplicitNamingStrategy implementations out-of-the-box.  Applications
are also free to plug in custom implementations.

There are multiple ways to specify the ImplicitNamingStrategy to use.  First, applications can specify
the implementation using the `hibernate.implicit_naming_strategy` configuration setting which accepts:

* pre-defined "short names" for the out-of-the-box implementations
+
`default`:: for `org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl` - an alias for `jpa`
`jpa`:: for `org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl` - the JPA 2.0 compliant naming strategy
`legacy-hbm`:: for `org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl` - compliant with the original Hibernate NamingStrategy
`legacy-jpa`:: for `org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl` - compliant with the legacy NamingStrategy developed for JPA 1.0, which was unfortunately unclear in many respects regarding implicit naming rules
`component-path`:: for `org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl` - mostly follows `ImplicitNamingStrategyJpaCompliantImpl` rules, except that it uses the full composite paths, as opposed to just the ending property part
+
* reference to a Class that implements the `org.hibernate.boot.model.naming.ImplicitNamingStrategy` contract
* FQN of a class that implements the `org.hibernate.boot.model.naming.ImplicitNamingStrategy` contract

Secondly, applications and integrations can leverage `org.hibernate.boot.MetadataBuilder#applyImplicitNamingStrategy`
to specify the ImplicitNamingStrategy to use.  See
<<chapters/bootstrap/Bootstrap.adoc#bootstrap,Bootstrap>> for additional details on bootstrapping.



[[PhysicalNamingStrategy]]
==== PhysicalNamingStrategy

Many organizations define rules around the naming of database objects (tables, columns, foreign keys, etc).
The idea of a PhysicalNamingStrategy is to help implement such naming rules without having to hard-code them
into the mapping via explicit names.

While the purpose of an ImplicitNamingStrategy is to determine that an attribute named `accountNumber` maps to
a logical column name of `accountNumber` when not explicitly specified, the purpose of a PhysicalNamingStrategy
would be, for example, to say that the physical column name should instead be abbreviated `acct_num`.

[NOTE]
====
It is true that the resolution to `acct_num` could have been handled using an `ImplicitNamingStrategy` in this case.

But the point here is the separation of concerns. The `PhysicalNamingStrategy` will be applied regardless of whether
the attribute explicitly specified the column name or whether we determined that implicitly. The
`ImplicitNamingStrategy` would only be applied if an explicit name was not given. So, it all depends on needs
and intent.
====

The default implementation is to simply use the logical name as the physical name.  However
applications and integrations can define custom implementations of this PhysicalNamingStrategy
contract.  Here is an example PhysicalNamingStrategy for a fictitious company named Acme Corp
whose naming standards are to:

* prefer underscore-delimited words rather than camel casing
* replace certain words with standard abbreviations

.Example PhysicalNamingStrategy implementation
====
[source,java]
----
include::{sourcedir}/AcmeCorpPhysicalNamingStrategy.java[]
----
====

There are multiple ways to specify the PhysicalNamingStrategy to use.  First, applications can specify
the implementation using the `hibernate.physical_naming_strategy` configuration setting which accepts:

* reference to a Class that implements the `org.hibernate.boot.model.naming.PhysicalNamingStrategy` contract
* FQN of a class that implements the `org.hibernate.boot.model.naming.PhysicalNamingStrategy` contract

Secondly, applications and integrations can leverage `org.hibernate.boot.MetadataBuilder#applyPhysicalNamingStrategy`.
See <<chapters/bootstrap/Bootstrap.adoc#bootstrap,Bootstrap>> for additional details on bootstrapping.



