2010-09-01 14 views
5

Quindi ho questo schema DB esistente con un numero di tabelle che voglio modellare con JPA/Hibernate. Ogni tabella ha lo stesso gruppo di 30 colonne aggiuntive (per consentire l'espansione di runtime del numero di campi registrati).È possibile definire dinamicamente i nomi delle colonne in 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), 
} 

ho intenzione di definire semplici classi per ogni tabella

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

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

    @Id 
    Long id = null; 
} 

, definire i parametri addizionali comuni in una classe comune

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

mentre questo lavoro, non come la natura hardcoded della classe.

Vorrei modellare ogni set di stringhe, campi lunghi e doppi come un ulteriore gruppo di parametri, e quindi avere gruppi 0..9. Questo mi permetterebbe di aggiungere facilmente gruppi extra in seguito, se necessario.

Se utilizzo la soluzione di mapping xml, è possibile determinare dinamicamente il nome corretto della colonna quando si genera il file .hbm.xml per ogni tabella. Preferirei usare una soluzione annotata, ma esiste un modo per sovrascrivere il metodo @Column getName() in modo che possa restituire un nome di colonna generato dinamicamente?

risposta

12

È necessario creare un numero personalizzato NamingStrategy.

Supponendo di usare la primavera e l'ibernazione con JPA, ecco un frammento di configurazione con un NamingStrategy personalizzato:

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

Se non si utilizza la primavera, la configurazione sarà diverso, ma è comunque possibile utilizzare un costume NamingStrategy (vedi Implementing a NamingStrategy dalla documentazione di Hibernate).

In ogni caso, ecco un campione NamingStrategy che costruisce i nomi di tabella del modulo TYPE1_TYPE2 per unire le tabelle e aggiunge un prefisso comune a tutte le tabelle:

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

Questo lo farà davvero, +1 –

Problemi correlati