每个实体的Hibernate命名策略

时间:2014-03-25 15:46:51

标签: java hibernate jpa

我有一个全局命名策略,但对于一些实体,我想使用另一个。在jpa或hibernate中是否可能?

澄清:我不想使用@Table(name =“xxx”)或@Column(name =“xxx”)。我问的是命名策略组件(例如这里描述:Hibernate naming strategy)。这是一个推断出你的列名和表名的组件

1 个答案:

答案 0 :(得分:2)

我在Hibernate源代码中看不到任何方法。 EntityBinder使用ObjectNameNormalizer.NamingStrategyHelper创建名称,它从Configuration.namingStrategy(全局一个)或通过MetadataImpl并登陆的复杂路径获取命名策略无处(没有用)。

因此您可能会手动覆盖覆盖字段名称。我甚至没有看到明显的方法来获得关于该领域的背景,所以我认为即使是一种分裂脑的命名策略看起来也是不可能的。

更新:在看到@ anthony-accioly的答案后,我以为我最后一句可能是错的。所以我测试了它如下

package internal.sandbox.domain;

@Entity
public class SomeEntity {

    private String id;
    private String someField;

    @Id
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getSomeField() {
        return someField;
    }

    public void setSomeField(String someField) {
        this.someField = someField;
    }
}

如下JpaConfiguration

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories("internal.sandbox.dao")
@Import(DataSourceConfiguration.class)
public class JpaConfiguration {

    @Bean
    @Autowired
    public LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean(DataSource dataSource) {

        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setDatabasePlatform("org.hibernate.dialect.PostgreSQL82Dialect");
        vendorAdapter.setDatabase(Database.POSTGRESQL);

        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setPackagesToScan("internal.sandbox"); // note, no ".domain"
        factory.setDataSource(dataSource);

        Properties properties = new Properties();
        properties.setProperty("hibernate.cache.use_second_level_cache", "false");
        properties.setProperty("hibernate.ejb.naming_strategy", "org.hibernate.cfg.ImprovedNamingStrategy");

        factory.setJpaProperties(properties);

        return factory;
    }
    ...

Spring Data DAO如下

public interface SomeEntityDao extends CrudRepository<SomeEntity, String> {
}

和集成测试如下

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {ApplicationConfiguration.class, JpaConfiguration.class})
public class SomeEntityDaoIntegrationTests {

    @Autowired
    private SomeEntityDao someEntityDao;

    @Test
    public void testSave() {

        SomeEntity someEntity = new SomeEntity();
        someEntity.setId("foo");
        someEntity.setSomeField("bar");

        this.someEntityDao.save(someEntity);
    }
}

我在ImprovedNamingStrategy中添加了断点,并使用&#34; SomeEntity&#34;来调用classToTableName()。并且使用&#34; someField&#34;来调用propertyToColumnName()

换句话说,包裹信息不会被传入,因此至少在此设置中,它不能用于根据包名称应用不同的命名策略。