[hibernate-dev] Naming and "naming strategies"
Steve Ebersole
steve at hibernate.org
Tue Jan 13 13:43:37 EST 2015
As I am working on 5.0, one of the things I am trying to accomplish is to
make the handling of table/column names more consistent and better
defined. The first step in that is to properly define the terms used often
throughout the codebase.
The first level of naming is the "given" name of a table/column. The given
name might be:
* explicit - explicitly specified by the user, as in @Table(
name="explicit_name" )
* implicit - not explicitly specified by the user and thus implicitly
determined (by JPA rules, "naming strategy", etc).
Next, we have a logical name which is a normalized form of the "given"
name. This is the form used to reference tables/columns internally. E.g.,
its how we resolve @Column(..., table="xyz"). More on this form later.
Finally we have the physical name of the thing, which is the actual name of
the table/column in the database. Again, this is generally a normalization
of the given name based on Dialect, "naming strategy", etc.
Today, we have a very messy concept called a NamingStrategy. I say it is
messy because it tries to combine unrelated concerns. So I still plan to
split this as I have outlined elsewhere into:
1) ImplicitNamingStrategy
2) PhysicalNamingStrategy
Which brings up my first question to y'all. Do we need a contract for
LogicalNamingStrategy? As I have said, the logical names are the things
used to resolve references. Allowing people to plug in custom strategies
for how that normalization works could be very dangerous. But even more
than that, is it really interesting to be able to hook into that process?
Historically, these names are all represented by String. So I also propose
to shift this to use that Identifier class we developed for the metamodel
redesign. For those that may be unfamiliar, it essentially combines the
String name with a "quoted" boolean:
public class Identifier {
private final String text;
private final boolean isQuoted;
...
}
Table names, then, are an aggregation of 3 Identifiers: one for catalog,
one for schema, one for table name. Same for named constraints
(ultimately, which is part of a improvement for 6.0 to allow indexes,
constraints, etc to be created in a separate schema from tables).
Since a major goal for 5.0 is to continue to use the org.hibernate.mapping
package as the representation of the mapping information, we obviously want
to minimize changes there to only what is completely essential. To that
end, if we are going to use Identifier over String stuff in the
org.hibernate.mapping package will need to deal with both; internally they
will hold the Identifier and use that to implement the String-based
name-related methods they expose.
Lastly I wanted to discuss the details of the logical names. For tables,
we currently qualify the table name with the catalog/schema info. There is
a mismatch in this regard when it comes to remaining a pure JPA
implementation. Consider @Column( ..., table="some_table"). Ultimately we
need to be able to qualify that with catalog/schema in order to be able to
construct a matching logical name (to be able to pair that with the
referenced org.hibernate.mapping.Table later). This is trivial when table
names are unique across all the catalogs/schemas (when there is only one
"some_table" in all the mapped catalogs/schemas). But is poses a problem
when the same table name is used from different schemas (e.g., when
"some_table" is mapped from both "schema1" and "schema2"). So we have a
choice. Since JPA does not say what is legal/illegal for the @Column.table
attribute, it is feasible for us to allow @Column.table to contain the
catalog/schema information in these cases as a selector. The only other
option I can see is to define a limitation that says that a table name must
be unique for a given entity across all catalogs/schemas. I don't think
that is generally a restrictive limitation. What are y'alls thoughts?
Perhaps this is one argument for allowing pluggable LogicalNamingStrategy?
More information about the hibernate-dev
mailing list