初始 SessionFactory 创建失败 - org.hibernate.MappingException:表 X 中的关联引用未映射的类:Y

问题描述 投票:0回答:1

我正在将应用程序从 Hibernate 4 迁移到 Hibernate 5。 我无法通过命名策略取胜。当然我已经读过: hibernate ImprovedNamingStrategy 会覆盖实体中的表名称 并且 ImprovedNamingStrategy 在 Hibernate 5 中不再工作

我已经将

AnnotationConfiguration
更改为
Configuration
,现在我有:

private void reloadHibernateSessionFactoryFromConf(Map<String, String> prop) {
        try {
            sessionFactory = null;
            Configuration config = new Configuration(); //hibernate5

            for(Map.Entry<String, String> entry : prop.entrySet()) {
                config.setProperty(entry.getKey(), entry.getValue());
            }
            if(namingStrategy!=null){
                configuration.setNamingStrategy(namingStrategy); //code which I think spoil application
            }
            if(annotatedEntityPackages!=null){
                addAnnotatedClasses(config);
            }
            sessionFactory = config.configure().buildSessionFactory();
        } catch (final HibernateException e) {
            LOGGER.error("SessionFactory creation failed", e);
        }

namingStrategy
放置者:

<property name="namingStrategy">
            <bean class="org.hibernate.cfg.ImprovedNamingStrategy"/>
        </property>

我已经尝试过发表评论了

configuration.setNamingStrategy(namingStrategy);
。我尝试了
configuration.setPhysicalNamingStrategy(PhysicalNamingStrategyImpl.INSTANCE);
但也尝试过
CamelCase
UpperCase
等,每次错误都是一样的。无论我对这个
namingStrategy
类做什么都不会被映射。

示例类:

public class UpperCaseNamingStrategy extends PhysicalNamingStrategyStandardImpl {

    @Override
    public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {
        return context.getIdentifierHelper().toIdentifier(
                StringUtils.upperCase(name.getText(), Locale.ENGLISH));
    }

    @Override
    public Identifier toPhysicalCatalogName(final Identifier name, final JdbcEnvironment context) {
        return context.getIdentifierHelper().toIdentifier(
                StringUtils.upperCase(name.getText(), Locale.ENGLISH));
    }

    @Override
    public Identifier toPhysicalSchemaName(final Identifier name, final JdbcEnvironment context) {
        return context.getIdentifierHelper().toIdentifier(
                StringUtils.upperCase(name.getText(), Locale.ENGLISH));
    }

    @Override
    public Identifier toPhysicalSequenceName(final Identifier name, final JdbcEnvironment context) {
        return context.getIdentifierHelper().toIdentifier(
                StringUtils.upperCase(name.getText(), Locale.ENGLISH));
    }

    @Override
    public Identifier toPhysicalTableName(final Identifier name, final JdbcEnvironment context) {
        return context.getIdentifierHelper().toIdentifier(
                StringUtils.upperCase(name.getText(), Locale.ENGLISH));
    }

}

但我仍然可以在日志中看到: org.hibernate.MappingException:表 X 中的关联引用未映射的类:Y 在 org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:709) 在 org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:746) 在repository.legacy.HibernateSessionManager.reloadHibernateSessionFactoryFromConf

那么

org.hibernate.cfg.ImprovedNamingStrategy
在 hibernate 5 中的实现是什么呢?

@编辑

其实我用的是:

public class PhysicalNamingStrategyImpl extends PhysicalNamingStrategyStandardImpl implements Serializable {

    public static final PhysicalNamingStrategyImpl INSTANCE = new PhysicalNamingStrategyImpl();

    @Override
    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
        return new Identifier(addUnderscores(name.getText()), name.isQuoted());
    }

    @Override
    public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {
        return new Identifier(addUnderscores(name.getText()), name.isQuoted());
    }


    protected static String addUnderscores(String name) {
        final 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);
    }
}

并完全删除:

<property name="namingStrategy">
     <bean class="org.hibernate.cfg.ImprovedNamingStrategy"/>
</property>

但我不认为这是正确的解决方案,因为我可以在运行时看到很多问题。

java hibernate
1个回答
0
投票

尝试以下操作:

  1. 正确配置:

    // 设置物理和隐式命名策略 config.setPhysicalNamingStrategy(new PhysicalNamingStrategyImpl()); config.setImplicitNamingStrategy(ImplicitNamingStrategyLegacyJpaImpl.INSTANCE);

  2. 检查实体映射:

Ensure that all your entities are correctly annotated with @Entity and that all entity classes are registered in the configuration
(即在 addAnnotatedClasses(config) 中列出或通过 config.addPackage("com.example") 列出)。 当 Hibernate 找不到实体或尝试映射与不存在的类的关联时,经常会出现您看到的错误。 仔细检查域模型中的映射(表、列和关联)是否正确。

  1. 修复实体名称和表名称映射:如果您使用自定义表或列名称,请确保它们与您生成的表名称匹配
    PhysicalNamingStrategy

示例:@Table(name = "USER_ACCOUNT")

并且您的策略将 userAccount 转换为 user_account,除非该表在数据库中确实名为 USER_ACCOUNT,否则您将遇到问题。

更新代码:

private void reloadHibernateSessionFactoryFromConf(Map<String, String> prop) {
    try {
        sessionFactory = null;
        Configuration config = new Configuration(); //hibernate5

        // Set properties
        for (Map.Entry<String, String> entry : prop.entrySet()) {
            config.setProperty(entry.getKey(), entry.getValue());
        }

        // Set naming strategies
        config.setPhysicalNamingStrategy(new PhysicalNamingStrategyImpl());
        config.setImplicitNamingStrategy(ImplicitNamingStrategyLegacyJpaImpl.INSTANCE);

        // Add annotated classes
        if (annotatedEntityPackages != null) {
            addAnnotatedClasses(config);
        }

        // Build session factory
        sessionFactory = config.configure().buildSessionFactory();
    } catch (final HibernateException e) {
        LOGGER.error("SessionFactory creation failed", e);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.