需要帮助为Hibernate 5中的外键列名实现ImplicitNamingStrategy [英] Need help in implementing ImplicitNamingStrategy for foreign key column names in Hibernate 5

查看:147
本文介绍了需要帮助为Hibernate 5中的外键列名实现ImplicitNamingStrategy的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过重写ImplicitNamingStrategyJpaCompliantImpl类中的方法determineForeignKeyName来为外键列名添加下划线,但不知何故它不起作用。下面是我创建的类,

  public class CustomNamingStrategy extends ImplicitNamingStrategyJpaCompliantImpl implements Serializable {

public static final CustomNamingStrategy INSTANCE = new CustomNamingStrategy();



/ **
*从给定的类名产生复数表名
* @使用下划线返回类名的复数形式而不是混合的情况。
* /
@Override
protected String transformEntityName(EntityNaming entityNaming){
return Noun.pluralOf(addUnderscores(StringHelper.unqualify(entityNaming.getEntityName())));
}

protected static String addUnderscores(String name){
StringBuilder buf = new StringBuilder(name.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。插入(i ++,'_');
}
}
返回buf.toString()。toLowerCase(Locale.ROOT);
}

@Override
public Identifier determineForeignKeyName(ImplicitForeignKeyNameSource source){

return toIdentifier(
NamingHelper.INSTANCE.generateHashedFkName(
FK,
source.getTableName(),
source.getReferencedTableName(),
addUnderscorestocolumns(source.getColumnNames())
),
source。 getBuildingContext()
);
}


public List< Identifier> addUnderscorestocolumns(List< Identifier> columnNamesList){

List< Identifier> underscorecolumns = new ArrayList< Identifier>();

for(int i = 0; i< columnNamesList.size(); i ++){
underscorecolumns.add(Identifier.toIdentifier(addUnderscores(columnNamesList.get(i).getText ))));
}
返回下划线列;



$ b @Override
public Identifier determineBasicColumnName(ImplicitBasicColumnNameSource source){

return toIdentifier(transformAttributePathCustom(source。 getAttributePath()),source.getBuildingContext());


protected String transformAttributePathCustom(AttributePath attributePath){
return addUnderscores(attributePath.getProperty());





$ p
$ b $ p所以,除了使用determineForeignKeyName方法,其他方法按预期工作,如为表格添加复数名称和下划线。当我通过代码进行调试时,我可以看到控制进入了外键列和下划线的determineForeignKeyName方法,但是当控件进入InflightMetadataCollectorImpl类(org.hibernate.boot.internal)时,我只能看到引用列是添加的,但不是列名的下划线。



是否有任何其他方法需要为外键列名实现或者我的实现中有任何错误?请提出建议。

解决方案

NamingHelper.INSTANCE.generateHashedFkName()生成哈希名称。
您需要类似这样的内容
$ b $ $ p $ @Override
public IdentifierdefinedForeignKeyName(ImplicitForeignKeyNameSource source){
返回标识符(
FK_+
source.getTableName()。getText()+_+
source.getReferencedTableName()。getText()+_+
addUnderscorestocolumns(source.getColumnNames()),
source.getBuildingContext());
}

你可以参考一个例子
Hibernate5NamingStrategy



标识符determineForeignKeyName(ImplicitForeignKeyNameSource source)不用于为这个SQL生成列名称,但是外键约束名称如 F_users_fk_address

  alter table users 
add constraint F_users_fk_address
外键(fk_address)
引用user_addresses(f_pid)

要指定外键列名称,您需要重写此方法

标识符determineJoinColumnName(ImplicitJoinColumnNameSource源)



请参阅: JoinColumnStrategyTest.java


I am trying to add underscores for the foreign key column names by overriding the method determineForeignKeyName in ImplicitNamingStrategyJpaCompliantImpl class, but somehow its not working. Below is the class i created,

public class CustomNamingStrategy extends ImplicitNamingStrategyJpaCompliantImpl implements Serializable{

    public static final CustomNamingStrategy INSTANCE=new CustomNamingStrategy ();



    /**
     * Produces a plural table name from the given class name
     * @return a pluralized version of the class name using underscores instead of mixed case.
     */
    @Override
    protected String transformEntityName(EntityNaming entityNaming) {
        return Noun.pluralOf(addUnderscores(StringHelper.unqualify(entityNaming.getEntityName())));
    }

    protected static String addUnderscores(String name) {
        StringBuilder buf = new StringBuilder(name.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++, '_');
            }
        }
        return buf.toString().toLowerCase(Locale.ROOT);
    }

    @Override
    public Identifier determineForeignKeyName(ImplicitForeignKeyNameSource source) {

        return toIdentifier(
                NamingHelper.INSTANCE.generateHashedFkName(
                        "FK",
                        source.getTableName(),
                        source.getReferencedTableName(),
                        addUnderscorestocolumns(source.getColumnNames())
                ),
                source.getBuildingContext()
        );
    }


    public List<Identifier> addUnderscorestocolumns(List<Identifier> columnNamesList) {

        List<Identifier> underscorecolumns = new ArrayList<Identifier>();

        for (int i = 0; i < columnNamesList.size(); i++) {
                        underscorecolumns.add(Identifier.toIdentifier(addUnderscores(columnNamesList.get(i).getText())))  ;
        }
        return underscorecolumns;
    }



   @Override
    public Identifier determineBasicColumnName(ImplicitBasicColumnNameSource source) {

        return toIdentifier(transformAttributePathCustom(source.getAttributePath()), source.getBuildingContext());
    }

    protected String transformAttributePathCustom(AttributePath attributePath) {
        return addUnderscores(attributePath.getProperty());
    }

  }

So, except the determineForeignKeyName method, others methods are working as expected, like adding plural names and underscore for the tables. When i debug through the code, i can see the control going into the determineForeignKeyName method for the foreign key columns and underscores are added, but when the control goes to InflightMetadataCollectorImpl class (org.hibernate.boot.internal), i can see only referenced column is added, but not the underscores for the column name.

Is there any other method i need to implement for foreign key column names or i there any error in my implementation? Please suggest.

解决方案

NamingHelper.INSTANCE.generateHashedFkName() generates a hashed name. You need something like this

@Override
public Identifier determineForeignKeyName(ImplicitForeignKeyNameSource source) {
    return toIdentifier(
                "FK_" +
                source.getTableName().getText() + "_" +
                source.getReferencedTableName().getText() + "_" +
              addUnderscorestocolumns(source.getColumnNames()),
        source.getBuildingContext());
}

You can refer as an example Hibernate5NamingStrategy

The method Identifier determineForeignKeyName(ImplicitForeignKeyNameSource source) is not used to generate column names, but foreign key constraint names like F_users_fk_address for this SQL

alter table users 
  add constraint F_users_fk_address 
  foreign key (fk_address) 
  references user_addresses (f_pid)

To specify foreign key column names you need to override this method

Identifier determineJoinColumnName(ImplicitJoinColumnNameSource source)

Refer this: JoinColumnStrategyTest.java

这篇关于需要帮助为Hibernate 5中的外键列名实现ImplicitNamingStrategy的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆