2016-11-24 4 views
0

私は今太陽に来たバグ/問題で戻っています。通常、私はH2DBのローカル開発と変更をテストしますが、わかっているように、これはOracleとMSSQLでも機能しなければなりません。 この問題が再び発生しました。 鍵COR_VIEWSETTINGSCOR_USERSETTINGS_FK0およびCOR_VIEWSETTINGSCOR_USERSETTINGS_FK1は自動的に生成され、Oracleデータベースでは長すぎます。 これらのキーの作成方法を知るために、エンティティUserSettingsとUserViewSettingsが表示されます。 ヒント:エンティティを見落とし、混乱させるような編集をすることができます。多分あなたはまだ私を助けることができます。自動Hibernateインデックスの作成が長すぎます

Wildfly 10.0.0にHibernate 5.2で始まるUserSettings

/** 

     The Class UserSettings. 

*/ 
@org.hibernate.envers.Audited 
@DataObject(value = UserSettings.DATA_OBJECT_NAME) 
@CRUDDefinition(supportsRead = true, supportsCreate = true, supportsUpdate = true, supportsDelete = true) 
@Entity(name = UserSettings.DATA_OBJECT_NAME) 
@NamedQuery(name = UserSettings.DATA_OBJECT_NAME, query = "from userSettings e where e.name = :name") 
@javax.persistence.Inheritance(strategy = javax.persistence.InheritanceType.TABLE_PER_CLASS) 
@AttributeOverrides({ @AttributeOverride(name = "id", column = @Column(name = "USERSETTINGS_ID")) 
}) 
@Table(name = "COR_USERSETTINGS", indexes = { 
    @javax.persistence.Index(name="COR_USERSETTINGS_FK0", columnList = "SETTINGSTYPE_ID"), 
    @javax.persistence.Index(name="COR_USERSETTINGS_FK1", columnList = "USER_ID"), 
} 
) 
public class UserSettings extends NamedRevisionEntity implements NameSettingsType, NameSettings 
{ 
    /** The Constant serialVersionUID. */ 
    private static final long serialVersionUID = 1L; 

    /** The Constant DATA_OBJECT_NAME. */ 
    public static final String DATA_OBJECT_NAME = "userSettings"; 

    @javax.persistence.Basic(fetch = javax.persistence.FetchType.EAGER, optional = false) 
    @Column(name = "SETTINGS", nullable = false, unique = false, insertable = true, updatable = true) 
    @javax.persistence.Lob 
    private java.lang.String settings; 

    @javax.persistence.ManyToOne(fetch = javax.persistence.FetchType.EAGER, optional = false) 
    @javax.persistence.JoinColumn(name = "SETTINGSTYPE_ID", nullable = false, unique = false, insertable = true, updatable = true) 
    private SettingsType settingsType; 

    @javax.persistence.ManyToOne(fetch = javax.persistence.FetchType.EAGER, optional = true) 
    @javax.persistence.JoinColumn(name = "USER_ID", nullable = true, unique = false, insertable = true, updatable = true) 
    private User user; 



    public SettingsType getSettingsType() 
    { 
    return settingsType; 
    } 

    public void setSettingsType(SettingsType settingsType) 
    { 
    this.settingsType = settingsType; 
    } 

    public User getUser() 
    { 
    return user; 
    } 

    public void setUser(User user) 
    { 
    this.user = user; 
    } 

    public java.lang.String getSettings() 
    { 
    return settings; 
    } 

    public void setSettings(java.lang.String settings) 
    { 
    this.settings = settings; 
    } 

    @Override 
    public String getDataObjectName() 
    { 
    return DATA_OBJECT_NAME; 
    } 



    @Override 
    public String toString() 
    { 
    StringBuilder builder = new StringBuilder(super.toString()); 

    builder.append(", "); 
    try 
    { 
     builder.append(ToStringUtils.referenceToString("settingsType", "SettingsType", this.settingsType)); 
    } 
    catch(Exception ex) 
    { 
     builder.append(ex.getClass().getName() ); 
     builder.append(": "); 
     builder.append(ex.getMessage()); 
    } 
    builder.append(", "); 
    try 
    { 
     builder.append(ToStringUtils.referenceToString("user", "User", this.user)); 
    } 
    catch(Exception ex) 
    { 
     builder.append(ex.getClass().getName() ); 
     builder.append(": "); 
     builder.append(ex.getMessage()); 
    } 

    builder.append("]"); 
    return builder.toString(); 
    } 

} 

UserViewSettings

/** 

     The Class UserViewSettings. 

*/ 
@org.hibernate.envers.Audited 
@DataObject(value = UserViewSettings.DATA_OBJECT_NAME) 
@CRUDDefinition(supportsRead = true, supportsCreate = true, supportsUpdate = true, supportsDelete = true) 
@Entity(name = UserViewSettings.DATA_OBJECT_NAME) 
@AttributeOverrides({ @AttributeOverride(name = "id", column = @Column(name = "VIEWSETTINGS_ID")) 
}) 
@Table(name = "COR_VIEWSETTINGS", uniqueConstraints = { 
    @javax.persistence.UniqueConstraint(name="COR_VIEWSETTINGS_UNQ1", columnNames = { "NAME", "SETTINGSTYPE_ID", "VIEW_NAME", "VIEWTYPE_ID" }), 
} 
, indexes = { 
    @javax.persistence.Index(name="COR_VIEWSETTINGS_FK0", columnList = "VIEWTYPE_ID"), 
} 
) 
public class UserViewSettings extends UserSettings implements NameViewName, NameViewType 
{ 
    /** The Constant serialVersionUID. */ 
    private static final long serialVersionUID = 1L; 

    /** The Constant DATA_OBJECT_NAME. */ 
    public static final String DATA_OBJECT_NAME = "userViewSettings"; 

    @javax.persistence.Basic(fetch = javax.persistence.FetchType.EAGER, optional = false) 
    @Column(name = "VIEW_NAME", nullable = false, unique = false, insertable = true, updatable = true) 
    private java.lang.String viewName; 

    @javax.persistence.ManyToOne(fetch = javax.persistence.FetchType.EAGER, optional = true) 
    @javax.persistence.JoinColumn(name = "VIEWTYPE_ID", nullable = true, unique = false, insertable = true, updatable = true) 
    private ViewType viewType; 



    public java.lang.String getViewName() 
    { 
    return viewName; 
    } 

    public void setViewName(java.lang.String viewName) 
    { 
    this.viewName = viewName; 
    } 

    public ViewType getViewType() 
    { 
    return viewType; 
    } 

    public void setViewType(ViewType viewType) 
    { 
    this.viewType = viewType; 
    } 

    @Override 
    public String getDataObjectName() 
    { 
    return DATA_OBJECT_NAME; 
    } 



    @Override 
    public String toString() 
    { 
    StringBuilder builder = new StringBuilder(super.toString()); 

    builder.append(", "); 
    builder.append("viewName"); 
    builder.append("="); 
    builder.append(this.viewName); 
    builder.append(", "); 
    try 
    { 
     builder.append(ToStringUtils.referenceToString("viewType", "ViewType", this.viewType)); 
    } 
    catch(Exception ex) 
    { 
     builder.append(ex.getClass().getName() ); 
     builder.append(": "); 
     builder.append(ex.getMessage()); 
    } 

    builder.append("]"); 
    return builder.toString(); 
    } 

} 

とOracleデータベース11は、その自動生成されたキーCOR_VIEWSETTINGSCOR_USERSETTINGS_FK0エラーになりますおよびCOR_VIEWSETTINGSCOR_USERSETTINGS_当然FK1はデータベースにとって長すぎます。

私はHibernateのNamingStrategiesを見て、いくつか試してみましたが、彼らは私のためにエラーを変更しませんでした。

どのようにこれらのキーの生成に影響を与えることができますか?

編集:今、私はをorg.hibernate.boot.model.namingパッケージでクラスImplicitIndexNameSourceが、インターネットを発見した

2016-11-29 09:22:03,190 DEBUG [org.hibernate.SQL] (ServerService Thread Pool -- 58) create index COR_USERSETTINGS_FK0 on COR_USERSETTINGS (SETTINGSTYPE_ID) 
2016-11-29 09:22:03,190 DEBUG [org.hibernate.SQL] (ServerService Thread Pool -- 58) create index COR_USERSETTINGS_FK1 on COR_USERSETTINGS (USER_ID) 
2016-11-29 09:22:03,190 DEBUG [org.hibernate.SQL] (ServerService Thread Pool -- 58) create index COR_VIEWSETTINGSCOR_USERSETTINGS_FK0 on COR_VIEWSETT INGS(SETTINGSTYPE_ID) 
2016-11-29 09:22:03,190 DEBUG [org.hibernate.SQL] (ServerService Thread Pool -- 58) create index COR_VIEWSETTINGSCOR_USERSETTINGS_FK1 on COR_VIEWSETTINGS (USER_ID) 
2016-11-29 09:22:03,190 DEBUG [org.hibernate.SQL] (ServerService Thread Pool -- 58) create index COR_VIEWSETTINGS_FK0 on COR_VIEWSETTINGS (VIEWTYPE_ID) 

だからDEBUGをオンにするには、私にこれを与えました私はこれで何ができるのかを実際に例を挙げておらず、それは長い間長い間空のクラスであるようです。

EDIT 2:

前の編集は、間違った道のようです。これらのログが作成される場所を見つけました。それはSchemaCreatorImplから呼び出されるです。だから私はフレームワークをもっと深く掘り下げる必要がありますが、もし誰かがこれを見たら。これは正しい道でしょうか?彼が私が望むことをするようにコードを修正することはできますか?私は多くのことを助けていただければ幸いです

final String indexNameForCreation; 
if (dialect.qualifyIndexName()) { 
    indexNameForCreation = jdbcEnvironment.getQualifiedObjectNameFormatter().format(
      new QualifiedNameImpl(
        index.getTable().getQualifiedTableName().getCatalogName(), 
        index.getTable().getQualifiedTableName().getSchemaName(), 
        jdbcEnvironment.getIdentifierHelper().toIdentifier(index.getName()) 
      ), 
      jdbcEnvironment.getDialect() 
    ); 
} 
else { 
    indexNameForCreation = index.getName(); 
} 
final StringBuilder buf = new StringBuilder() 
     .append("create index ") 
     .append(indexNameForCreation) 
     .append(" on ") 
     .append(tableName) 
     .append(" ("); 

boolean first = true; 
Iterator<Column> columnItr = index.getColumnIterator(); 
while (columnItr.hasNext()) { 
    final Column column = columnItr.next(); 
    if (first) { 
     first = false; 
    } 
    else { 
     buf.append(", "); 
    } 
    buf.append((column.getQuotedName(dialect))); 
} 
buf.append(")"); 
return new String[] { buf.toString() }; 

:これらの行にStandardIndexExportで作成したインデックス取得年代から犯人であるhbm2ddlのようです。これは本当にイライラしています

答えて

0

だから私はそれを働かせました。 これを見つける可能性があり、同じ問題が発生する可能性のある将来の人にお答えします。

索引キーは、休止状態が参照されているoracleの方言によって作成されます。したがって、実行する必要があったのは、メソッドgetIndexExporterをオーバーライドし、カスタムIndexExporterを指すカスタムOracleDialectを実装することでした。このIndexExporterでは、キーの作成方法を変更できます。私の場合、私はこのようなソリューションを固定:

/** 
    * Gets the correct index name if it is a index for a TABLE_PER_CLASS inheritance and longer than 
    * 30 chars. 
    * 
    * @param index the index to decide for 
    * @return the correct index name 
    */ 
    private String getCorrectIndexName(Index index) 
    { 
    if (index.getTable() instanceof DenormalizedTable && index.getName().length() > 30) 
    { 
     String prefixedTable = index.getTable().getName(); 
     String tableName = prefixedTable.substring(prefixedTable.indexOf('_') + 1, prefixedTable.length()); 
     tableName = shortenName(tableName); 
     Iterator<Column> columnItr = index.getColumnIterator(); 
     String reference; 

     if (columnItr.hasNext()) 
     { 
     reference = extractReference(columnItr.next()); 
     } 
     else 
     { 
     /** backup strategy to prevent exceptions */ 
     reference = shortenName(NamingHelper.INSTANCE.hashedName(index.getName())); 
     } 

     return tableName + "_" + reference; 
    } 
    return index.getName(); 
    } 

    /** 
    * Extract the reference column of the index and hash the full name before shortening it with 
    * shortenName(). 
    * 
    * @param index the index to extract the reference from. 
    * @return the reference with an appended _FK(hashedReference). 
    */ 
    private String extractReference(Column column) 
    { 
    String reference = column.getQuotedName(dialect); 
    String md5Hash = NamingHelper.INSTANCE.hashedName(reference); 
    md5Hash = md5Hash.substring(md5Hash.length() - 4, md5Hash.length()); 
    reference = shortenName(reference); 

    return reference + "_FK" + md5Hash; 
    } 

    /** 
    * Shorten the name to a maximum of 11 chars if it's longer. 
    * 
    * @param reference the reference to shorten 
    * @return the shortened string 
    */ 
    private static String shortenName(String reference) 
    { 
    if (reference.length() > 11) 
    { 
     return reference.substring(0, 11); 
    } 
    return reference; 
    } 

これはgetSqlCreateStringsオーバーライドさの関数で呼び出されなければなりませんでした。変更された行は次のようになります。

String indexName = getCorrectIndexName(index); 
    indexNameForCreation = jdbcEnvironment.getQualifiedObjectNameFormatter() 
     .format(
      new QualifiedNameImpl(index.getTable().getQualifiedTableName().getCatalogName(), 
       index.getTable().getQualifiedTableName().getSchemaName(), jdbcEnvironment.getIdentifierHelper().toIdentifier(indexName)), 
      jdbcEnvironment.getDialect()); 

誰かを助けることを望みます。

関連する問題