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

时间:2016-05-12 18:51:49

标签: java hibernate

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

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

  }

因此,除了determineForeignKeyName方法之外,其他方法正在按预期工作,例如为表添加多个名称和下划线。当我通过代码调试时,我可以看到控件进入DetermForeignKeyName方法的外键列和下划线被添加,但当控件转到InflightMetadataCollectorImpl类(org.hibernate.boot.internal)时,我只能看到引用列已添加,但不添加列名称的下划线。

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

2 个答案:

答案 0 :(得分:2)

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)不用于生成列名,而是用于此SQL的外键约束名称,如F_users_fk_address

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

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

Identifier determineJoinColumnName(ImplicitJoinColumnNameSource source)

请参阅:JoinColumnStrategyTest.java

答案 1 :(得分:1)

根据v.ladynev的建议,我覆盖了我的类中的determineJoinColumnName方法,

arr[0]

现在按预期工作。