NamingStrategy в Hibernate 5, совместимый с Hibernate 4

В настоящее время мы пытаемся переместить наше веб-приложение с Wildfly 9.0.2 на Wildfly 10.1.0 и переходим с Hibernate 4.3.10 на 5.0.10.

Мы никогда не определяли наши собственные NamingStrategyиспользуя любые имена, которые Hibernate выберет для наших сущностей (наша база данных Postgresql создается через hbm2ddl).

Теперь, в Hibernate 5, у нас есть неизвестные ошибки столбцов, так как соглашение об именах изменилось. В частности, в таблицах соединений имена столбцов теперь основаны на истинном классе, а не на родительском: например, там, где мы имеем UserEntity который наследует от AgentEntityпрежде чем мы получили agentEntity_id колонка, теперь это userEntity_id колонка.

Я пробую четыре существующих Hibernate ImplicitNamingStrategies (jpa, legacy-jpa, legacy-hbm и component-path) в нашем persistence.xmlбез успеха: каждый из них отличается от старой стратегии.

Итак, есть ли способ избежать переписывания моей собственной стратегии, чтобы сохранить соответствие нашей старой модели?

1 ответ

У меня была такая же проблема при переходе на Hibernate 5, хотя у нас есть серверная часть Oracle. Мне удалось достичь стратегии именования, аналогичной той, что была у меня в комплекте с Hibernate 4, используя оба org.hibernate.boot.model.naming.ImplicitNamingStrategy а также org.hibernate.boot.model.naming.PhysicalNamingStrategy,

Вот как выглядит определение моего компонента из контекста моего приложения:

@Bean
@Primary
public static JpaProperties jpaProperties() {
  final Map<String, String> hibernateConfig = newHashMap();
  hibernateConfig.put("hibernate.implicit_naming_strategy",      
  "org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl");
  hibernateConfig.put("hibernate.physical_naming_strategy",
  "com.anyapp.CustomNamingStrategy");

  final JpaProperties jpaProperties = new JpaProperties();
  jpaProperties.setProperties(hibernateConfig);
  jpaProperties.setDatabase(ORACLE);
  jpaProperties.setDatabasePlatform(ORACLE12C_DIALECT);
  jpaProperties.setGenerateDdl(false);
  jpaProperties.setShowSql(false);
  return jpaProperties;
}

Самым раздражающим было выяснить, какие стратегии именования применять, каким образом и что мне пришлось реализовать CustomNamingStrategy сам по себе, так как Hibernate не обеспечивает PhysicalNamingStrategy что соответствует названию наследия ImprovedNamingStrategy,

Вот содержимое моего CustomNamingStrategy:

package com.anyapp;

import org.apache.commons.lang.StringUtils;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;

public class CustomNamingStrategy implements PhysicalNamingStrategy {

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

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

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

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

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

    private Identifier convert(Identifier identifier) {
        if (identifier == null || StringUtils.isBlank(identifier.getText())) {
            return identifier;
        }

        String regex = "([a-z])([A-Z])";
        String replacement = "$1_$2";
        String newName = identifier.getText().replaceAll(regex, replacement).toLowerCase();
        return Identifier.toIdentifier(newName);
    }
}

Возможно, вам придется настроить регулярное выражение в соответствии с вашими потребностями, но это то, что сработало для меня.

Другие вопросы по тегам