首页 > 解决方案 > 物理命名策略已注册但在持久性时未触发

问题描述


物理命名策略已注册但在持久性期间未触发。

我正在尝试为我的 dropwizard hibernate bundle 配置 PhysicalNaming Strategy

public abstract class CustomHibernateBundle<T extends io.dropwizard.Configuration> extends ScanningHibernateBundle<T> {

protected CustomHibernateBundle(String pckg) {
    this(pckg, new SessionFactoryFactory());
}

protected CustomHibernateBundle(String pckg, SessionFactoryFactory sessionFactoryFactory) {
    this(new String[]{pckg}, sessionFactoryFactory);
}

protected CustomHibernateBundle(String[] pckgs, SessionFactoryFactory sessionFactoryFactory) {
    super(pckgs, sessionFactoryFactory);
}

public void configure(Configuration configuration) {
    super.configure(configuration);
    configuration.setPhysicalNamingStrategy(new CustomNamingStrategy());
}
}



public class CustomNamingStrategy implements PhysicalNamingStrategy {
private String tableName(Identifier identifier) {
 if (identifier == null)
        return null;
    String newName = identifier.getText();
    String customID = (String) MDC.get("CUSTOM-ID");
    if (!StringUtils.isEmpty(customID) && taint.equalsIgnoreCase("custom_id"))
        newName = newName + "_custom";
    return newName;
}

@Override
public Identifier toPhysicalCatalogName(Identifier identifier, JdbcEnvironment jdbcEnvironment) {
    return identifier;
}

@Override
public Identifier toPhysicalSchemaName(Identifier identifier, JdbcEnvironment jdbcEnvironment) {
    return identifier;
}

@Override
public Identifier toPhysicalTableName(Identifier identifier, JdbcEnvironment jdbcEnvironment) {
    return jdbcEnvironment.getIdentifierHelper().toIdentifier(tableName(identifier));
}

@Override
public Identifier toPhysicalSequenceName(Identifier identifier, JdbcEnvironment jdbcEnvironment) {
    return identifier;
}

@Override
public Identifier toPhysicalColumnName(Identifier identifier, JdbcEnvironment jdbcEnvironment) {
    return identifier;
}
}

启动时,命名策略类正在正确注册。但是当我尝试坚持时,实际的命名策略并没有发挥作用。

我也尝试过使用

hibernate.naming.physical_strategy: com.someorg.CustomStrategy

在我的 YAML 文件中,但没有用。

标签: javahibernate

解决方案


对我有用的是在配置上调用方法(而不是插入属性),

configuration.setPhysicalNamingStrategy(new ReallyCoolNamingStrategy());

以及财产:

hibernate.globally_quoted_identifiers: true

对于 DropWizard + Hibernate Web 服务器:

  1. 按照 DropWizard 的设置说明进行操作

  2. 将所需的设置放入您的配置中:

    • 在这个片段中,我添加了命名策略。

    • 对于 PostgreSQL,我有globally quoted identifiersasfalse

database:
  driverClass: org.postgresql.Driver
  url: jdbc:postgresql://localhost:5432/mule?currentSchema=public
  user: mule-admin
  password:
  properties:
    hibernate.dialect: org.hibernate.dialect.PostgreSQL10Dialect
    hibernate.physical_naming_strategy: net.sf.zoftwhere.hibernate.SnakeCaseNamingStrategy
    hibernate.globally_quoted_identifiers: false
    hibernate.hbm2ddl.auto: update
    hibernate.show_sql: false
    hibernate.format_sql: false
  1. 更新 Hibernate Bundle 的初始化:

    • 这里存储的属性用于硬编码策略。
  public static <T extends DatabaseConfiguration> HibernateBundle<T> getHibernateBundle() {
    return new HibernateBundle<>(AbstractEntity.class, persistenceEntities()) {
      @Override
      public DataSourceFactory getDataSourceFactory(T configuration) {
        return configuration.getDataSourceFactory();
      }

      @Override
      protected void configure(org.hibernate.cfg.Configuration configuration) {
        final String namingStrategy = configuration.getProperty("hibernate.physical_naming_strategy");

        if (SnakeCaseNamingStrategy.class.getName().equals(namingStrategy)) {
          configuration.setPhysicalNamingStrategy(new SnakeCaseNamingStrategy());
        } else if (MacroCaseNamingStrategy.class.getName().equals(namingStrategy)) {
          configuration.setPhysicalNamingStrategy(new MacroCaseNamingStrategy());
        }
      }
    };
  }

  public static Class<?>[] persistenceEntities() {
    return new Class<?>[]{
        Account.class,
        AccessToken.class,
        ShellSession.class,
    };
  }
  1. 仔细检查您的策略:
    • 确保为空值返回空值。
    • 确保传递isQuoted参数。
...

  @Override
  public Identifier toPhysicalTableName(final Identifier identifier, final JdbcEnvironment jdbcEnv) {
    return convertToSnakeCase(identifier);
  }

  protected Identifier convertToSnakeCase(final Identifier identifier) {
    if (identifier == null) {
      return null;
    }

    return Identifier.toIdentifier(snakeCase(identifier.getText()), identifier.isQuoted());
  }

  protected String snakeCase(String input) {
    return input.replaceAll("([a-z])([A-Z])", "$1_$2")
        .replaceAll("([A-Z])([A-Z][a-z])", "$1_$2")
        .toLowerCase();
  }

...

希望这可以帮助。

DropWizard 1.3.13 Hibernate 5.4.3.Final Java 11.0.2 (Oracle)


推荐阅读