Hibernate naming strategy per entity

hibernate, java, jpa

Solution

I don't see a way in the Hibernate source code. The `EntityBinder` is coming up with names using `ObjectNameNormalizer.NamingStrategyHelper`, which gets the naming strategy from either `Configuration.namingStrategy` (the global one) or from a complex path which goes through `MetadataImpl` and lands nowhere (no usages).

So you're likely stuck with overriding field names manually. I don't even see an obvious way to get context about the field, so I think even a split-brain naming strategy looks like it's out of the question.

Update: After seeing @anthony-accioly's answer, I thought I that last sentence may have been wrong. So I tested it as follows

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

with a `JpaConfiguration` as follows

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

a Spring Data DAO as follows

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

and an integration test as follows

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

I put breakpoints in the `ImprovedNamingStrategy`, and `classToTableName()` was called with "SomeEntity" and `propertyToColumnName()` was called with "someField".

In other words, package information isn't being passed in, so at least in this setup, it can't be used to apply a different naming strategy based on package name.

Problem

I have one global naming strategy but for a few entities I want to use a different one. Is it possible in jpa or hibernate? clarification: i don't want to use @Table(name="xxx") nor @Column(name="xxx"). i'm asking about naming strategy component (described for example here: Hibernate naming strategy). that's a component that infer the column and table names for you

Original source

Related problems