2010-09-01 25 views
5

所以我有这个现有的数据库模式与我想用JPA/Hibernate建模的许多表。每个 表具有相同的一组30个附加列(以允许运行时扩展记录的字段数 )。是否可以在Hibernate/JPA中动态定义列名?

CREATE TABLE XX 
    (
    "ID"   VARCHAR2(100 BYTE) NOT NULL ENABLE, 
    "USER_LABEL"  VARCHAR2(256 BYTE), 
    "CREATION_DATE" NUMBER(38,0) NOT NULL ENABLE, 
    "ADD_STR_FIELD_0" VARCHAR2(200 BYTE), 
    "ADD_LNG_FIELD_0" NUMBER(38,0), 
    "ADD_DBL_FIELD_0" NUMBER(38,0), 
    "ADD_STR_FIELD_1" VARCHAR2(200 BYTE), 
    "ADD_LNG_FIELD_1" NUMBER(38,0), 
    "ADD_DBL_FIELD_1" NUMBER(38,0), 
    "ADD_STR_FIELD_2" VARCHAR2(200 BYTE), 
    "ADD_LNG_FIELD_2" NUMBER(38,0), 
    "ADD_DBL_FIELD_2" NUMBER(38,0), 
    "ADD_STR_FIELD_3" VARCHAR2(200 BYTE), 
    "ADD_LNG_FIELD_3" NUMBER(38,0), 
    "ADD_DBL_FIELD_3" NUMBER(38,0), 
    "ADD_STR_FIELD_4" VARCHAR2(200 BYTE), 
    "ADD_LNG_FIELD_4" NUMBER(38,0), 
    "ADD_DBL_FIELD_4" NUMBER(38,0), 
    "ADD_STR_FIELD_5" VARCHAR2(200 BYTE), 
    "ADD_LNG_FIELD_5" NUMBER(38,0), 
    "ADD_DBL_FIELD_5" NUMBER(38,0), 
    "ADD_STR_FIELD_6" VARCHAR2(200 BYTE), 
    "ADD_LNG_FIELD_6" NUMBER(38,0), 
    "ADD_DBL_FIELD_6" NUMBER(38,0), 
    "ADD_STR_FIELD_7" VARCHAR2(200 BYTE), 
    "ADD_LNG_FIELD_7" NUMBER(38,0), 
    "ADD_DBL_FIELD_7" NUMBER(38,0), 
    "ADD_STR_FIELD_8" VARCHAR2(200 BYTE), 
    "ADD_LNG_FIELD_8" NUMBER(38,0), 
    "ADD_DBL_FIELD_8" NUMBER(38,0), 
    "ADD_STR_FIELD_9" VARCHAR2(200 BYTE), 
    "ADD_LNG_FIELD_9" NUMBER(38,0), 
    "ADD_DBL_FIELD_9" NUMBER(38,0), 
} 

我打算定义简单的类为每个表

import javax.persistence.Entity; 
import javax.persistence.Id; 
import javax.persistence.Table; 

@Entity 
@Table(name="XX") 
public class XX { 

    @Id 
    Long id = null; 
} 

,然后在一个公共类

import javax.persistence.Column; 

public abstract class AdditionalParameters { 

    @Column(name="ADD_STR_FIELD_0") 
    private String addStringField0 = null; 
    @Column(name="ADD_LNG_FIELD_0") 
    private Long addLongField0 = null; 
    @Column(name="ADD_DBL_FIELD_0") 
    private Double addDoubleField0 = null; 
    .... 
    .... 
    .... 
    @Column(name="ADD_STR_FIELD_8") 
    private String addStringField8 = null; 
    @Column(name="ADD_LNG_FIELD_8") 
    private Long addLongField8 = null; 
    @Column(name="ADD_DBL_FIELD_8") 
    private Double addDoubleField8 = null; 
} 

定义了常见的附加参数,而这会工作,我不就像班级的硬编码一样。

我想为每组字符串,长字段和双字段建模为一个附加参数组,然后 有0..9个组。如果需要,这将允许我稍后添加额外的组。

如果我使用xml映射解决方案,我可以在为每个表生成.hbm.xml 时动态确定正确的列名称。我宁愿使用注解的解决方案,但有没有办法来覆盖@Column getName()方法 ,这样我可以返回一个动态生成的列名称?

回答

12

您需要创建自定义NamingStrategy

假设你使用的弹簧与JPA休眠,这里是一个配置片段与一个自定义的NamingStrategy:

<bean id="entityManagerFactory" 
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="persistenceUnitName" value="myunit" /> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="persistenceXmlLocation" 
       value="classpath:META-INF/persistence.xml" /> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
      <property name="showSql" value="false" /> 
      <property name="generateDdl" value="true" /> 
      <property name="database" value="MYSQL" /> 
     </bean> 
    </property> 
    <property name="jpaProperties"> 
     <props> 
      <prop 
       key="hibernate.ejb.naming_strategy"> 
       com.yourcompany.CustomNamingStrategy 
      </prop> 
     </props> 
    </property> 
</bean> 

如果你不使用的弹簧,配置会有所不同,但你仍然可以使用自定义NamingStrategy(请参阅Hibernate文档中的Implementing a NamingStrategy)。

不管怎么说,这是建立形式TYPE1_TYPE2用于连接表的表名,并增加了一个共同的前缀的所有表的样本NamingStrategy:

public class CustomNamingStrategy extends ImprovedNamingStrategy { 

    private static final long serialVersionUID = 1L; 
    private static final String PREFIX = "PFX_"; 

    @Override 
    public String classToTableName(final String className) { 
     return this.addPrefix(super.classToTableName(className)); 
    } 

    @Override 
    public String collectionTableName(final String ownerEntity, 
      final String ownerEntityTable, final String associatedEntity, 
      final String associatedEntityTable, final String propertyName) { 
     return this.addPrefix(super.collectionTableName(ownerEntity, 
       ownerEntityTable, associatedEntity, associatedEntityTable, 
       propertyName)); 
    } 

    @Override 
    public String logicalCollectionTableName(final String tableName, 
      final String ownerEntityTable, final String associatedEntityTable, 
      final String propertyName) { 
     return this.addPrefix(super.logicalCollectionTableName(tableName, 
       ownerEntityTable, associatedEntityTable, propertyName)); 
    } 

    private String addPrefix(final String composedTableName) { 

     return PREFIX 
       + composedTableName.toUpperCase().replace("_", ""); 

    } 

} 
+1

这将做到这一点确实+1 – 2010-09-01 13:53:12

相关问题