当前位置: 首页 > 面试题库 >

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

谢海阳
2023-03-14
问题内容

我正在尝试通过覆盖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)时,我只能看到引用的控件列已添加,但未添加列名的下划线。

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


问题答案:

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



 类似资料:
  • 需要在 SQL 中将主键列更新为自动递增 我越来越不犯错, 关键字“身份”附近的语法不正确。

  • 我正在为Clojure做一个练习题,应该很简单,但实际上却让我很头疼,问题描述如下: two-fer或2-fer是二对一的缩写。一个代表你,一个代表我。给定一个名称,返回一个带有消息的字符串:“One for X, one for me。”其中X是给定的名称。但是,如果缺少名称,请返回字符串:“One for you, one for me。” 这就是我所尝试的: 然而,我最终得到了以下单元测试输

  • 我正在开发一个应用程序,它从云Firestore中获取一些文档,并在一个RecyclerView中显示文档的内容。我希望遵循关注分离的原则,并因此使用MVVM架构来构建应用程序。我已经使用FireStoreRecyclerAdapter为RecyclerView实现了一个数据类模型和适配器。 我已经在一个引导项目中工作过,该项目使用了MVVM体系结构和LiveData和Room。在该项目中,实现的

  • 然后,这需要转到数据库,该数据库向工作人员发送返回消息,告诉他们该成员已被添加。 只有工作人员在和系统通话,没有人。

  • 我在mysql工作台上设计了一个数据库。当我转到forward engineer时,我得到了(错误号:121),因为我在多个表中使用了相同的外键,我意识到这是不允许的。我有相当多的连接表,主要是n:m关系。对于这些连接表中的大多数,我都使用复合主键(由2个外键组成)。我的问题是我必须重命名这些主键和外键是唯一的吗?谢谢你的帮助。 (在下面的代码中,我还没有重命名外键)

  • 我想在OpenNLP中进行命名实体识别功能的培训。我根据http://opennlp.apache.org/documentation/1.5.2-incubating/manual/opennlp.html#tools.namefind写了一段代码 我从一个试图训练“数字”的简单示例开始,并在这样的训练文件中标记了所有\d: 代码是: 我有以下例外: 我猜“数字”不在默认注释列表中。我该怎么办?