Java 可以在Hibernate/JPA中动态定义列名吗?

Java 可以在Hibernate/JPA中动态定义列名吗?,java,hibernate,orm,jpa,Java,Hibernate,Orm,Jpa,因此,我有一个现有的DB模式,其中有许多表,我想用JPA/Hibernate建模。每个 表具有相同的30个附加列组(以允许在运行时扩展字段的数量) (已记录) 我计划为每个表定义简单的类 import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="XX") public class XX { @Id Long

因此,我有一个现有的DB模式,其中有许多表,我想用JPA/Hibernate建模。每个 表具有相同的30个附加列组(以允许在运行时扩展字段的数量) (已记录)

我计划为每个表定义简单的类

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()方法
这样我就可以返回动态生成的列名了?

您需要创建一个自定义列名

假设您在JPA中使用spring和hibernate,下面是一个带有自定义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>
<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>
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("_", "");

    }

}