改进的命名策略在 Hibernate 5 中不再起作用

2023-11-22

我有简单的 spring-jpa 配置,其中配置了 HibernateImprovedNamingStrategy。这意味着如果我的实体类有一个变量userName,那么 Hibernate 应该将其转换为user_name用于查询数据库。但在我升级到 Hibernate 5 后,此命名转换停止工作。我收到错误:

错误:“字段列表”中存在未知列“user0_.userName”

这是我的休眠配置:

@Configuration
@EnableJpaRepositories("com.springJpa.repository")
@EnableTransactionManagement
public class DataConfig {

    @Bean
    public DataSource dataSource(){
        DriverManagerDataSource ds = new DriverManagerDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/test");
        ds.setUsername("root");
        ds.setPassword("admin");
        return ds;
    }


    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(){ 

        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setShowSql(Boolean.TRUE);
        vendorAdapter.setDatabase(Database.MYSQL);

        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setDataSource(dataSource());
        factory.setPackagesToScan("com.springJpa.entity");


        Properties jpaProperties = new Properties();

        jpaProperties.put("hibernate.ejb.naming_strategy","org.hibernate.cfg.ImprovedNamingStrategy");
        jpaProperties.put("hibernate.dialect","org.hibernate.dialect.MySQL5InnoDBDialect");

        factory.setJpaProperties(jpaProperties);
        factory.afterPropertiesSet();
        return factory;
    }

    @Bean
    public SharedEntityManagerBean entityManager() {
        SharedEntityManagerBean entityManager = new SharedEntityManagerBean();
        entityManager.setEntityManagerFactory(entityManagerFactory().getObject());
        return entityManager;
    }



    @Bean
    public PlatformTransactionManager transactionManager() {
        JpaTransactionManager txManager = new JpaTransactionManager();
        txManager.setEntityManagerFactory(entityManagerFactory().getObject());
        return txManager;
    }

    @Bean
    public ImprovedNamingStrategy namingStrategy(){
        return new ImprovedNamingStrategy();
    }
}

这是我的实体类:

@Getter
@Setter
@Entity
@Table(name="user")
public class User{

    @Id
    @GeneratedValue
    private Long id;

    private String userName;
    private String email;
    private String password;
    private String role;

}

我不想在 @Column 注释中显式命名我的数据库字段。我希望我的配置可以隐式地将驼峰式大小写转换为下划线。

请指导。


感谢您发布您自己的解决方案。它对我设置 Hibernate 5 命名策略很有帮助!

The hibernate.ejb.naming_strategyHibernate 5.0 之前的属性似乎分为两部分:

  • hibernate.physical_naming_strategy
  • hibernate.implicit_naming_strategy

这些属性的值没有实现NamingStrategy界面一样hibernate.ejb.naming_strategy。有两个用于这些目的的新接口:

  • org.hibernate.boot.model.naming.PhysicalNamingStrategy
  • org.hibernate.boot.model.naming.ImplicitNamingStrategy

Hibernate 5 只提供了一种实现PhysicalNamingStrategy (PhysicalNamingStrategyStandardImpl)假设物理标识符名称与逻辑标识符名称相同。

有几种实现方式ImplicitNamingStrategy但我发现没有一个相当于旧的ImprovedNamingStrategy. (See: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl)

所以,我实现了自己的PhysicalNamingStrategy这很简单:

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

请注意,addUnderscores()方法来自于原来的org.hibernate.cfg.ImprovedNamingStrategy.

然后,我将此物理策略设置到 persistence.xml 文件中:

  <property name="hibernate.physical_naming_strategy" value="my.package.PhysicalNamingStrategyImpl" />

将 Hibernate 5 命名策略设置为以前版本的设置是一个陷阱。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

改进的命名策略在 Hibernate 5 中不再起作用 的相关文章

随机推荐