【问题标题】:Hibernate naming strategy per entity每个实体的休眠命名策略
【发布时间】:2014-05-03 14:11:47
【问题描述】:

我有一个全局命名策略,但对于一些实体,我想使用不同的。在jpa或hibernate中可以吗?

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

【问题讨论】:

  • @Entity(name="yourNameHere") 怎么样?或者你还有什么意思是命名策略?请澄清。
  • 通过命名策略我的意思是“避免手动提供列名的方法”:stackoverflow.com/questions/19146246/hibernate-naming-strategy
  • piotrek,我想每个人的重点都是。对默认用例使用全局命名策略,并使用注释覆盖非默认用例。如果会比实现自己的NamingStrategy 更干净。
  • 我想做 global=ImprovedNamingStrategy 并在 A 类中设置 SimpleNamingStrategy。我不想自己写
  • @piotrek,我了解您的问题,我要告诉您的是您的选择是:1) 选择 ImprovedNamingStrategy 作为默认值并使用标准 JPA 注释自定义 A 类或 2) 烹饪您的拥有NamingStrategy 以将不同的实体委托给不同的命名约定。后者是不可取的,除非您确实有很多实体应该由每个命名策略(无论是否自制)处理。

标签: java hibernate jpa


【解决方案1】:

我在 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 中设置了断点,classToTableName() 被“SomeEntity”调用,propertyToColumnName() 被“someField”调用。

换句话说,包信息没有被传入,所以至少在这个设置中,它不能用于根据包名称应用不同的命名策略。

【讨论】:

    猜你喜欢
    • 2020-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-28
    • 2010-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多