小编典典

在Hibernate 5中为外键列名称实现ImplicitNamingStrategy时需要帮助

hibernate

我正在尝试通过覆盖ImplicitNamingStrategyJpaCompliantImpl类中的方法defineForeignKeyName来为外键列名添加下划线,但是不起作用。下面是我创建的类,

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());
    }

  }

因此,除了defineForeignKeyName方法外,其他方法也可以按预期工作,例如为表添加复数名称和下划线。当我通过代码调试时,我可以看到该控件进入用于外键列的underlyForeignKeyName方法并添加了下划线,但是当该控件转到InflightMetadataCollectorImpl类(org.hibernate.boot.internal)时,我只能看到引用的控件列已添加,但未添加列名的下划线。

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


阅读 475

收藏
2020-06-20

共1个答案

小编典典

NamingHelper.INSTANCE.generateHashedFkName()生成一个哈希名称。你需要这样的东西

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

您可以作为示例参考 Hibernate5NamingStrategy

该方法Identifier determineForeignKeyName(ImplicitForeignKeyNameSource source)不用于生成列名,而是F_users_fk_address用于此SQL的外键约束名

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

要指定外键列名,您需要覆盖此方法

Identifier determineJoinColumnName(ImplicitJoinColumnNameSource source)

引用此:JoinColumnStrategyTest.java

2020-06-20