So i have this existing DB schema with a number of tables that i want to model with JPA/Hibernate. Each table has the same group of 30 additional columns ( to allow for runtime expansion of the number of fields recorded).
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),
}
I plan to define simple classes for each table
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="XX")
public class XX {
@Id
Long id = null;
}
and then define the common additional parameters in a common class
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;
}
while this will work, i don't like the hardcoded nature of the class.
I would like to model each set of string,long and double fields as an additional parameter group, and then have 0..9 groups. This would allow me easily add extra groups later if required.
If i use the xml mapping solution i can dynamically determine the correct column name when generating the .hbm.xml for each table. I would prefer to use an annotated solution, but is there a way to override the @Column getName() method so that i can return a dynamically generated column name?
Queries that are created at runtime by the application are called dynamic queries. Dynamic queries are created when we pass a simple JPA compliant query string to the createQuery method of the EntityManager class.
In this article, we will discuss how to change the column name in the Spring project using JPA. @Column annotation is used for Adding the column the name in the table of a particular MySQL database. Attribute: Name: The name of the column.
@Id annotation is the JPA is used for making specific variable primary key.
You need to create a custom NamingStrategy.
Assuming you use spring and hibernate with JPA, here is a configuration snippet with a custom 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>
If you don't use spring, configuration will be different, but you can still use a custom NamingStrategy (see Implementing a NamingStrategy from the Hibernate Documentation).
Anyway, here is a sample NamingStrategy that builds table names of the form TYPE1_TYPE2 for join tables and adds a common prefix to all tables:
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("_", "");
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With