Стратегия за именуване в 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, без успех: всеки се различава от старата стратегия.

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


person Xavier Portebois    schedule 12.04.2017    source източник


Отговори (1)


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

Ето как изглежда моята дефиниция на bean от контекста на моето приложение:

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

Може да се наложи да коригирате регулярния израз, за ​​да отговаря на вашите нужди, но това е, което работи за мен.

person lax1089    schedule 25.04.2017
comment
Съгласих се, също ми се струва, че Hibernate няма физическа стратегия за именуване, съвместима с тяхната наследена. Бихте ли искали да споделите вашата com.anyapp.CustomNamingStrategy? - person Xavier Portebois; 25.04.2017
comment
Добавих съдържанието на моята реализация CustomNamingStrategy към моя отговор - person lax1089; 25.04.2017