[hibernate-dev] Naming and "naming strategies"

Steve Ebersole steve at hibernate.org
Wed Jan 14 10:19:40 EST 2015


Something like:


public interface ImplicitNamingStrategy {
  public Identifier determinePrimaryTableName(ImplicitEntityNameSource
source);

  public Identifier determineJoinTableName(ImplicitJoinTableNameSource
source);

  public Identifier
determineCollectionTableName(ImplicitCollectionTableNameSource
source);

  public Identifier
determineDiscriminatorColumnName(ImplicitDiscriminatorColumnNameSource
source);

    public Identifier
determineTenantIdColumnName(ImplicitTenantIdColumnNameSource
source);

  public Identifier
determineAttributeColumnName(ImplicitAttributeColumnNameSource
source);

  public Identifier
determineCollectionJoinColumnName(ImplicitCollectionJoinColumnNameSource
source);

    ...
}


The sources are simply parameter objects providing access to information
needed to determine the implicit name.  For example:

/**
 * Defines the source for entity naming.  Between legacy Hibernate
requirements and
 * JPA requirements this is, unfortunately, multi-sourced.  This contract
allows
 * access to all source values.
 *
 * @author Steve Ebersole
 */
public interface ImplicitEntityNamingSource {
    /**
     * The FQN of the entity class.  Note, this may be {@code null} in the
case
     * of (non-JPA-compliant) dynamic entities).
  *
     * @return The entity class FQN, or {@code null} if a dynamic entity.
  */
  public String getEntityClassName();

  /**
     * Get the explicitly specified Hibernate entity name.  The Hibernate
name is
  * very much different from the JPA concept of entity name.
  *
  * @return The explicitly specified entity name
  */
  public String getExplicitEntityName();

  /**
  * The Hibernate entity name.  This might be either:<ul>
  *     <li>The explicitly specified entity name, if one</li>
  *     <li>The unqualified entity class name if no entity name was
explicitly specified</li>
  * </ul>
  *
   * @return The Hibernate entity name
  */
  public String getEntityName();

  /**
 * The JPA-specific entity name.  See {@link
javax.persistence.Entity#name()} for details.
     *
  * @return The JPA entity name, if one was specified.  May return {@code
null} if one
  * was not explicitly specified.
  */
  public String getJpaEntityName();
}

etc...

And then:

public interface PhysicalNamingStrategy {
    public Identifier toPhysicalCatalogName(Identifier name);

    public Identifier toPhysicalSchemaName(Identifier name);

    public Identifier toPhysicalTableName(Identifier name);

    public Identifier toPhysicalColumnName(Identifier name);
}

I think ultimately it makes sense to pass some additional information
into PhysicalNamingStrategy to give access to Dialect, etc.

On Wed, Jan 14, 2015 at 4:38 AM, Hardy Ferentschik <hardy at hibernate.org>
wrote:

> Hi,
>
> +1 for ImplicitNamingStrategy and PhysicalNamingStrategy
> What would be the contract of these strategies?
>
> I don't think LogicalNamingStrategy is necessary. I think this might
> just get too complicated for a user. Also, iiuc the logical name is for
> internal lookups.
>
> +1 for actual identifier classes. I think the code would become easier to
> understand
> and hopefully safer with these typed classes. I liked this approach when
> working
> on the metamodel branch. I would, however, not make it an interface. I
> also see
> this as a pre-mature optimisation
>
> > 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..
>
> What exactly do you mean with 'selector'?
>
> --Hardy
>
>
>
> On Tue, Jan 13, 2015 at 12:43:37PM -0600, Steve Ebersole wrote:
> > 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?
> > _______________________________________________
> > hibernate-dev mailing list
> > hibernate-dev at lists.jboss.org
> > https://lists.jboss.org/mailman/listinfo/hibernate-dev
>


More information about the hibernate-dev mailing list