2015-10-13 2 views
3

Je veux utiliser Hibernate 5.x. Avec hibernate 5.x il y a de nouvelles interfaces pour ImplicitNamingStrategy et PhysicalNamingStrategy.Hibernate 5 ImplicitNamingStrategy

Pour une propriété name d'une entité User Je souhaite avoir un nom de colonne user_name dans ma base de données. Je ne veux pas annoter toutes les propriétés avec @Column(name="..."). J'ai essayé d'écrire un ImplicitNamingStrategy personnalisé mais il n'y a aucun moyen d'obtenir le nom de l'entité propriétaire.

public class MyNamingStrategy extends ImplicitNamingStrategyComponentPathImpl 
{ 
    @Override 
    public Identifier determineBasicColumnName (ImplicitBasicColumnNameSource source) 
    { 
     // How to get the name of the owning entity? 
     String owningEntityName = "howdoigetthis"; 
     Identifier basicColumnName = super.determineBasicColumnName(source); 
     Identifier identifier = Identifier.toIdentifier(owningEntityName +"_" + basicColumnName.toString()); 
     return identifier; 
    } 
} 

est-il un moyen de préfixe chaque colonne avec la table (ou entité) nom en utilisant simplement un NamingStrategy?

+0

Ce message semble correspondre à vos besoins: http://stackoverflow.com/questions/32165694/spring-hibernate-5-naming-strategy-configuration. –

+0

@ AndréBlaszczyk Ce message que vous avez mentionné ne correspond pas à mes besoins. Il modifie simplement les noms des colonnes, mais ne les préfixe pas avec un nom de table. – Janning

Répondre

3

est ici une solution si vous ne me dérange pas un peu de réflexion sale:

@Override 
public Identifier determineBasicColumnName(final ImplicitBasicColumnNameSource source) 
{ 
    // Get 'this$0' field and make it accessible 
    Field ejb3ColumnField = null; 
    final Field[] sourceFields = source.getClass().getDeclaredFields(); 
    for (final Field sourceField : sourceFields) { 
     if (sourceField.getName().equals("this$0")) { 
      ejb3ColumnField = sourceField; 
     } 
    } 
    ejb3ColumnField.setAccessible(true); 

    // Get actual field object 
    String owningEntityName; 
    Ejb3Column ejb3Column; 
    try { 
     ejb3Column = (Ejb3Column) ejb3ColumnField.get(source); 
    } catch (
     IllegalArgumentException 
     | IllegalAccessException e) { 
     throw new RuntimeException(e); // (Or deal with this appropriately, e.g. log it.) 
    } 

    // The property holder path holds the owning entity's fully qualified name 
    final String owningEntityFullyQualifiedName = ejb3Column.getPropertyHolder().getPath(); 

    // The entity name is after the last dot in the fully qualified name 
    final String[] owningEntityTokens = owningEntityFullyQualifiedName.split("\\."); 
    owningEntityName = owningEntityTokens[owningEntityTokens.length - 1]; 

    final Identifier basicColumnName = super.determineBasicColumnName(source); 
    return Identifier.toIdentifier(owningEntityName + "_" + basicColumnName.toString()); 
} 
3

Ceci est ma solution finale basée sur la réponse Steve Chambers. Cette solution prend même en compte une dénomination explicite avec des annotations et corrige le nom de la colonne de jointure. Mais Steve devrait obtenir tous les mérites de sa réponse

public class JlotImplicitNamingStrategy extends ImplicitNamingStrategyComponentPathImpl 
{ 
    @Override 
    public Identifier determineJoinColumnName (ImplicitJoinColumnNameSource source) 
    { 
     String name = source.getReferencedColumnName().toString(); 
     Identifier identifier = toIdentifier(name, source.getBuildingContext()); 
     return identifier; 
    } 

    @Override 
    public Identifier determineBasicColumnName (ImplicitBasicColumnNameSource source) 
    { 
     try 
     { 
      Field ejb3ColumnField = source.getClass().getDeclaredField("this$0"); 
      ejb3ColumnField.setAccessible(true); 
      Ejb3Column ejb3Column = (Ejb3Column) ejb3ColumnField.get(source); 

      // explicit naming oder implicit 
      String tableName = ejb3Column.getPropertyHolder().getTable().getName(); 
      final Identifier basicColumnName = super.determineBasicColumnName(source); 
      String columnName = tableName + "_" + basicColumnName.toString(); 
      return Identifier.toIdentifier(columnName); 
     } 
     catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) 
     { 
      throw new RuntimeException(e); 
     } 
    } 
} 
2

J'ai mis en place les deux interfaces qui donne le résultat de 99,99% en mise en veille prolongée 4:

public class ImprovedNamingStrategy implements PhysicalNamingStrategy 
{ 

@Override 
public Identifier toPhysicalCatalogName(Identifier identifier, JdbcEnvironment jdbcEnv) 
{ 
    return convert(identifier); 
} 

@Override 
public Identifier toPhysicalColumnName(Identifier identifier, JdbcEnvironment jdbcEnv) 
{ 
    return convert(identifier); 
} 

@Override 
public Identifier toPhysicalSchemaName(Identifier identifier, JdbcEnvironment jdbcEnv) 
{ 
    return convert(identifier); 
} 

@Override 
public Identifier toPhysicalSequenceName(Identifier identifier, JdbcEnvironment jdbcEnv) 
{ 
    return convert(identifier); 
} 

@Override 
public Identifier toPhysicalTableName(Identifier identifier, JdbcEnvironment jdbcEnv) 
{ 
    return convert(identifier); 
} 

/** 
* Converts table name. 
* 
* @param identifier the identifier. 
* @return the identifier. 
*/ 
private Identifier convert(Identifier identifier) 
{ 
    if (identifier == null || StringUtils.isBlank(identifier.getText())) 
    { 
     return identifier; 
    } 

    final StringBuilder buf = new StringBuilder(identifier.getText().replace('.', '_')); 
    for (int i = 1; i < buf.length() - 1; i++) 
    { 
     if (
      Character.isLowerCase(buf.charAt(i - 1)) && 
      Character.isUpperCase(buf.charAt(i)) && 
      Character.isLowerCase(buf.charAt(i + 1)) 
      ) 
     { 
      buf.insert(i++, '_'); 
     } 
    } 
    String newName = Strings.toLowerCase(buf.toString()); 
    return Identifier.toIdentifier(newName); 
} 
} 

et

public class ImprovedImplicitNamingStrategy implements ImplicitNamingStrategy 
{ 
/** 
* The INSTANCE. 
*/ 
public static final ImprovedImplicitNamingStrategy INSTANCE = new ImprovedImplicitNamingStrategy(); 

/** 
* Constructor. 
*/ 
public ImprovedImplicitNamingStrategy() 
{ 
} 

/** 
* The determinePrimaryTableName. 
* 
* @param source the source. 
* @return the identifier. 
*/ 
@Override 
public Identifier determinePrimaryTableName(ImplicitEntityNameSource source) 
{ 
    if (source == null) 
    { 
     // should never happen, but to be defensive... 
     throw new HibernateException("Entity naming information was not provided."); 
    } 

    String tableName = transformEntityName(source.getEntityNaming()); 

    if (tableName == null) 
    { 
     // todo : add info to error message - but how to know what to write since we failed to interpret the naming source 
     throw new HibernateException("Could not determine primary table name for entity"); 
    } 
    return toIdentifier(tableName, source.getBuildingContext()); 
} 

/** 
* The determinePrimaryTableName. 
* 
* @param entityNaming the source. 
* @return the identifier. 
*/ 
protected String transformEntityName(EntityNaming entityNaming) 
{ 
    // prefer the JPA entity name, if specified... 
    if (StringHelper.isNotEmpty(entityNaming.getJpaEntityName())) 
    { 
     return entityNaming.getJpaEntityName(); 
    } 
    else 
    { 
     // otherwise, use the Hibernate entity name 
     return StringHelper.unqualify(entityNaming.getEntityName()); 
    } 
} 

/** 
* The determinePrimaryTableName. 
* 
* @param source the source. 
* @return the identifier. 
*/ 
@Override 
public Identifier determineJoinTableName(ImplicitJoinTableNameSource source) 
{ 
    final String ownerPortion = source.getOwningPhysicalTableName(); 
    final String ownedPortion; 
    if (source.getAssociationOwningAttributePath() != null) 
    { 
     ownedPortion = transformAttributePath(source.getAssociationOwningAttributePath()); 
    } 
    else 
    { 
     ownedPortion = source.getNonOwningPhysicalTableName(); 
    } 

    return toIdentifier(ownerPortion + "_" + ownedPortion, source.getBuildingContext()); 
} 

/** 
* The determinePrimaryTableName. 
* 
* @param source the source. 
* @return the identifier. 
*/ 
@Override 
public Identifier determineCollectionTableName(ImplicitCollectionTableNameSource source) 
{ 
    final String owningEntity = transformEntityName(source.getOwningEntityNaming()); 
    final String name = transformAttributePath(source.getOwningAttributePath()); 
    final String entityName; 
    if (!Strings.isNullOrEmpty(owningEntity)) 
    { 
     entityName = owningEntity + "_" + name; 
    } 
    else 
    { 
     entityName = name; 
    } 
    return toIdentifier(entityName, source.getBuildingContext()); 
} 

/** 
* The determinePrimaryTableName. 
* 
* @param source the source. 
* @return the identifier. 
*/ 
@Override 
public Identifier determineIdentifierColumnName(ImplicitIdentifierColumnNameSource source) 
{ 
    return toIdentifier(transformAttributePath(source.getIdentifierAttributePath()), source.getBuildingContext()); 
} 

/** 
* The determinePrimaryTableName. 
* 
* @param source the source. 
* @return the identifier. 
*/ 
@Override 
public Identifier determineDiscriminatorColumnName(ImplicitDiscriminatorColumnNameSource source) 
{ 
    return toIdentifier(
     source.getBuildingContext().getMappingDefaults().getImplicitDiscriminatorColumnName(), source.getBuildingContext()); 
} 

/** 
* The determinePrimaryTableName. 
* 
* @param source the source. 
* @return the identifier. 
*/ 
@Override 
public Identifier determineTenantIdColumnName(ImplicitTenantIdColumnNameSource source) 
{ 
    return toIdentifier(source.getBuildingContext().getMappingDefaults().getImplicitTenantIdColumnName(), source.getBuildingContext()); 
} 

/** 
* The determinePrimaryTableName. 
* 
* @param source the source. 
* @return the identifier. 
*/ 
@Override 
public Identifier determineBasicColumnName(ImplicitBasicColumnNameSource source) 
{ 
    return toIdentifier(transformAttributePath(source.getAttributePath()), source.getBuildingContext()); 
} 

/** 
* The determineJoinColumnName. 
* 
* @param source the source. 
* @return identifier. 
*/ 
@Override 
public Identifier determineJoinColumnName(ImplicitJoinColumnNameSource source) 
{ 
    final String name; 

    if (source.getNature() == ImplicitJoinColumnNameSource.Nature.ELEMENT_COLLECTION) 
    { 
     name = transformEntityName(source.getEntityNaming()) + '_' + source.getReferencedColumnName().getText(); 
    } 
    else 
    { 
     if (source.getAttributePath() == null) 
     { 
      name = source.getReferencedTableName().getText(); 
     } 
     else 
     { 
      name = transformAttributePath(source.getAttributePath()); 
     } 
    } 
    return toIdentifier(name, source.getBuildingContext()); 
} 

/** 
* The determinePrimaryTableName. 
* 
* @param source the source. 
* @return the identifier. 
*/ 
@Override 
public Identifier determinePrimaryKeyJoinColumnName(ImplicitPrimaryKeyJoinColumnNameSource source) 
{ 
    return source.getReferencedPrimaryKeyColumnName(); 
} 

/** 
* The determinePrimaryTableName. 
* 
* @param source the source. 
* @return the identifier. 
*/ 
@Override 
public Identifier determineAnyDiscriminatorColumnName(ImplicitAnyDiscriminatorColumnNameSource source) 
{ 
    return toIdentifier(
     transformAttributePath(source.getAttributePath()) + "_" + 
     source.getBuildingContext().getMappingDefaults().getImplicitDiscriminatorColumnName(), 
     source.getBuildingContext()); 
} 

/** 
* The determinePrimaryTableName. 
* 
* @param source the source. 
* @return the identifier. 
*/ 
@Override 
public Identifier determineAnyKeyColumnName(ImplicitAnyKeyColumnNameSource source) 
{ 
    return toIdentifier(
     transformAttributePath(source.getAttributePath()) + "_" + 
     source.getBuildingContext().getMappingDefaults().getImplicitIdColumnName(), 
     source.getBuildingContext()); 
} 

/** 
* The determinePrimaryTableName. 
* 
* @param source the source. 
* @return the identifier. 
*/ 
@Override 
public Identifier determineMapKeyColumnName(ImplicitMapKeyColumnNameSource source) 
{ 
    return toIdentifier(
     transformAttributePath(source.getPluralAttributePath()) + "_KEY", 
     source.getBuildingContext() 
    ); 
} 

/** 
* The determinePrimaryTableName. 
* 
* @param source the source. 
* @return the identifier. 
*/ 
@Override 
public Identifier determineListIndexColumnName(ImplicitIndexColumnNameSource source) 
{ 
    return toIdentifier(transformAttributePath(source.getPluralAttributePath()) + "_ORDER", source.getBuildingContext()); 
} 

/** 
* The determinePrimaryTableName. 
* 
* @param source the source. 
* @return the identifier. 
*/ 
@Override 
public Identifier determineForeignKeyName(ImplicitForeignKeyNameSource source) 
{ 
    return toIdentifier(
     NamingHelper.INSTANCE.generateHashedFkName(
      "FK", 
      source.getTableName(), 
      source.getReferencedTableName(), 
      source.getColumnNames() 
     ), 
     source.getBuildingContext() 
    ); 
} 

/** 
* The determinePrimaryTableName. 
* 
* @param source the source. 
* @return the identifier. 
*/ 
@Override 
public Identifier determineUniqueKeyName(ImplicitUniqueKeyNameSource source) 
{ 
    return toIdentifier(
     NamingHelper.INSTANCE.generateHashedConstraintName(
      "UK", 
      source.getTableName(), 
      source.getColumnNames() 
     ), 
     source.getBuildingContext() 
    ); 
} 

/** 
* The determinePrimaryTableName. 
* 
* @param source the source. 
* @return the identifier. 
*/ 
@Override 
public Identifier determineIndexName(ImplicitIndexNameSource source) 
{ 
    return toIdentifier(
     NamingHelper.INSTANCE.generateHashedConstraintName(
      "IDX", 
      source.getTableName(), 
      source.getColumnNames() 
     ), 
     source.getBuildingContext() 
    ); 
} 

/** 
* For JPA standards we typically need the unqualified name. However, a more usable 
* impl tends to use the whole path. This method provides an easy hook for subclasses 
* to accomplish that 
* 
* @param attributePath The attribute path 
* @return The extracted name 
*/ 
protected String transformAttributePath(AttributePath attributePath) 
{ 
    return attributePath.getProperty(); 
} 

/** 
* Easy hook to build an Identifier using the keyword safe IdentifierHelper. 
* 
* @param stringForm The String form of the name 
* @param buildingContext Access to the IdentifierHelper 
* @return The identifier 
*/ 
protected Identifier toIdentifier(String stringForm, MetadataBuildingContext buildingContext) 
{ 

    return buildingContext.getMetadataCollector() 
          .getDatabase() 
          .getJdbcEnvironment() 
          .getIdentifierHelper() 
          .toIdentifier(stringForm); 
} 
} 

N'Joy .