Defining a Data Entity
Migration of MAPPER data reports to database tables is informed by configuration metadata based on the Spring framework. The configuration addresses several aspects of translating MAPPER report data to a domain entity backed by a table:
identifying entity data tuples.
definition of RDBMS table and columns.
mapping of MAPPER report fields to database columns.
specification of Java persistence class that represents the domain entity in the MAPPER report.
Hibernate mapping between database table and persistence class.
The Spring bean primarily responsible for configuring the translation of a MAPPER report into a database
table is DataEntityHandler.
The features of the
DataEntityHandler
bean and their usage are explored in greater detail below.
Translation of the sample MAPPER report Footwear Orders - Information (RID 12D3954) is used as an example.
Identifying Data Tuples
It's important to identify which data lines in a MAPPER comprise a tuple (or row) of entity data, and how those tuples are organized.
In a typical MAPPER data report, each line beginning with a tab character contains columnar data fields for the primary entity represented by the report. In most reports, each tab line is treated as a distinct data tuple, although MJ supports composition of a data tuple from multiple lines.
A MAPPER data report may contain more than one kind of entity data based on the line type. Trailer lines sometimes occur immediately after a tab line, beginning with a line type character like asterisk or period. Such trailer lines usually specify an entirely different entity from the tab lines.
See more information on the structure of MAPPER data reports, including examples.
Defining the RDBMS Table
The database table created by MJ to host the MAPPER report data adheres to common, best practices such
as surrogate primary key, created-by-user, created-by-timestamp, last-updated-by-user and last-updated-by-timestamp columns.
The Footwear Orders example below shows setting the FOOTWEAR_ORDER_LINEITEM
table
name and custom column names for the surrogate key, last-updated-by-timestamp and created-by-user:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<bean id="orderEntityHandler"
. . .
p:tableName="FOOTWEAR_ORDER_LINEITEM"
p:surrogateKeyColumnName="fw_order_li_id"
p:updateTimestampColumnName="DATE_OF_LAST_UPDATE"
p:createUserColumnName="CREATED_BY_USER"
. . .
>
</bean>
. . .
</beans>
Notice the example above (along with the other examples on this page) use the XML shortcut with
the p-namespace.
The p-namespace uses the bean element's attributes, instead of nested <property/>
elements,
to specify property values and collaborating beans.
Defining the RDBMS Columns
The fields in the MAPPER report are stored as columns in the database table, where each column is
specified by a column definition bean. For most fields,
an AnnotatedColumnDef
bean defines the corresponding database column. Each column definition bean is then referenced by
the DataEntityHandler
bean. Below are two example column definition beans for
the Qty and Price fields in the Footwear Orders report. A la Spring, each
column is defined via arguments passed to the AnnotatedColumnDef
constructor:
<bean id="orderEntityHandler.coldefQuantity"
class="com.arsi.mj.maprpt.entity.handler.AnnotatedColumnDef">
<!-- MAPPER name, MAPPER type, entity attrname, column name, length, NULLABLE, data type -->
<constructor-arg index="0" value="Qty" />
<constructor-arg index="1">
<util:constant static-field="com.arsi.mj.datatype.MaprptDataType.INTEGER"/>
</constructor-arg>
<constructor-arg index="2" value="quantity"/>
<constructor-arg index="3" value="QTY"/>
<constructor-arg index="4" value="3"/>
<constructor-arg index="5" value="false"/>
<constructor-arg index="6">
<util:constant static-field="org.hibernate.type.StandardBasicTypes.INTEGER"/>
</constructor-arg>
</bean>
. . .
<bean id="orderEntityHandler.coldefPrice"
class="com.arsi.mj.maprpt.entity.handler.AnnotatedColumnDef">
<!-- MAPPER name, MAPPER type, entity attrname, column, length, scale, NULLABLE, data type -->
<constructor-arg index="0" value="Price" />
<constructor-arg index="1">
<util:constant static-field="com.arsi.mj.datatype.MaprptDataType.FLOAT"/>
</constructor-arg>
<constructor-arg index="2" value="price"/>
<constructor-arg index="3" value="PRICE"/>
<constructor-arg index="4" value="8"/>
<constructor-arg index="5" value="2"/>
<constructor-arg index="6" value="false"/>
<constructor-arg index="7">
<util:constant static-field="org.hibernate.type.StandardBasicTypes.BIG_DECIMAL"/>
</constructor-arg>
</bean>
The example AnnotatedColumnDef
beans are wired as dependencies (collaborating
bean references) via the ordinal column properties (column2
and
column7
) of the DataEntityHandler
bean
for Footwear Orders:
<bean id="orderEntityHandler"
. . .
p:column2-ref="orderEntityHandler.coldefQuantity"
. . .
p:column7-ref="orderEntityHandler.coldefPrice"
. . .
>
Note the actual column number don't matter; the column<N>
naming covention
simply permits definition of an arbitrary number of column properties on
the DataEntityHandler
bean.
Defining an Enumerated RDBMS Column
When a field in the MAPPER report is restricted to a set of known, discrete values, specify a Java enumeration with the column definition bean. Examples of this are shoe Type ("Basketball", "Running", "Golf", "Tennis") and Gender ("Womens", "Mens") in the Footwear Orders report. In these cases, field values from the report are mapped to enumerated values with StringKeyEnumMapping bean. The example mapping for the shoe Type is:
<bean id="orderEntityHandler.enumShoeType"
class="com.arsi.mj.maprpt.enums.StringKeyEnumMapping"
p:enumClassName="com.arsi.mj.testapp.hibgen.enums.ShoeType">
<property name="enumsFromProperties">
<value>
Basketball=BASKETBALL -> Basketball
Running=RUNNING -> Running
Golf=GOLF -> Golf
Tennis=TENNIS -> Tennis
</value>
</property>
</bean>
Important properties of the StringKeyEnumMapping
bean are:
enumClassName |
Full name of enumeration class, including package. For example,
com.arsi.mj.testapp.hibgen.enums.ShoeType . |
enumsFromProperties |
Defines enumerated constants and associated keys from a properties object. |
defineEnum |
Define an enumerated constant and specify it's associated key. |
Mapping of field values to enumerated values is most easily defined as properties via
the enumsFromProperties
method and the extended name/value
syntax supported by the method:
key=symbol->value
For StringKeyEnumMapping
, key is a field value from the MAPPER report, symbol is
an enumerated constant name and value is the enumerated constant value. Here is an example:
Basketball=BASKETBALL -> Basketball
where key, symbol and value are:
key |
Basketball |
Field value from MAPPER report for basketball shoes. |
symbol |
BASKETBALL |
The name of the enumerated constant. This is different from the name of the class
derived from java.lang.enum , which is
specified by enumClassName . |
value |
Basketball |
The value of the enumerated constant; this value is stored in the database column created for the attribute. Typically the same as key when migrating a MAPPER application, but a more succinct value may be supplied if key is unwieldy or multiple keys are mapped to the same enumerated value. |
MJ generates the ShoeType
enumeration:
package com.arsi.mj.testapp.hibgen.enums;
import com.arsi.mj.IGenericEnum;
/** Enumeration of <code>ShoeType</code>.*/
public enum ShoeType implements IGenericEnum {
TENNIS("Tennis"),
BASKETBALL("Basketball"),
RUNNING("Running"),
GOLF("Golf");
/** String value associated with each enumeration constant. */
private String value;
/** Restricted ctor for creating an instance of this class. */
private ShoeType(String aValue) {
this.value = aValue;
}
/**
* Get canonical name of the enumeration constant, which is the associated string value.
*
* @return
* canonical name, i.e., associated string value (e.g., if Java enum constant is
* <code>AVERAGE</code>, canonical name might be "AVG").
*/
public String asName() { return this.value; }
/**
* Given canonical name (associated string value) of an enumeration constant,
* return the Java enumeration constant.
*
* @param aValue
* associated string value (canonical name, e.g., "AVG").
* @return
* enumeration constant associated with string value (e.g., <code>AVERAGE</code>).
* @throws IllegalArgumentException
* if <code>aValue</code> is not associated with any enumeration constant.
*/
public static ShoeType asValueOf(String aValue) {
if (TENNIS.asName().equals(aValue))
return TENNIS;
else if (BASKETBALL.asName().equals(aValue))
return BASKETBALL;
else if (RUNNING.asName().equals(aValue))
return RUNNING;
else if (GOLF.asName().equals(aValue))
return GOLF;
else
throw new IllegalArgumentException("invalid enumeration value: " + aValue);
}
}
Similar to other fields, an AnnotatedColumnDef bean defines the database column that stores the enumerated entity attribute. The column definition bean for shoe Type is:
<bean id="orderEntityHandler.coldefShoeType"
class="com.arsi.mj.maprpt.entity.handler.AnnotatedColumnDef">
<!-- MAPPER name, MAPPER type, entity attrname, column name, length, NULLABLE, data type -->
<constructor-arg index="0" value="Type" />
<constructor-arg index="1">
<util:constant static-field="com.arsi.mj.datatype.MaprptDataType.STRING"/>
</constructor-arg>
<constructor-arg index="2" value="shoeType"/>
<constructor-arg index="3" value="SHOE_TYPE"/>
<constructor-arg index="4" value="10"/>
<constructor-arg index="5" value="false"/>
<constructor-arg index="6">
<util:constant static-field="org.hibernate.type.StandardBasicTypes.STRING"/>
</constructor-arg>
</bean>
References to the AnnotatedColumnDef
and StringKeyEnumMapping
collaborating beans are wired as dependencies via ordinal column
and
enumForColumn
properties of DataEntityHandler
bean:
<bean id="orderEntityHandler"
. . .
p:column3-ref="orderEntityHandler.coldefShoeType"
p:enumForColumn3-ref="orderEntityHandler.enumShoeType"
. . .
/>
DataEntityHandler Example: FootwearOrderLineitem
See the full Spring XML for
the Footwear Orders sample MAPPER report, including
configuration for translating order entity data into
the FootwearOrderLineitem
persistent, domain entity class
and FOOTWEAR_ORDER_LINEITEM
table.