Menu

round-trip-sample

Harry Gardner

Round Trip Code Generation Example
The Round Trip Code generation project, located in samples/round-trip directory, demonstrates how to configure dal4j in order to customize the generated pojos. The type of decorators that can be injected into generated pojos includes:

  • Entity relationships, use in conjunction with <readOnlyColumns>.
  • Global imports - imports added to every generated class.
  • Global Class level annotations - class annotations added to every generated Entity.
  • Class imports - Add imports to a specific class.
  • Class annotations - Add class level annotations to a specific class.
  • Class Code Injection - Add class specific code blocks to the generated entity.
  • Attribute Level Annotations - Annotations added to an attribute's get method.

These features allow customized Entities to be regenerated as the schema evolves. This concept is refered to as round-trip code generation and is something DAL4j strives to support.

Defining Entity Relationships
Do the following to allow entity relationships to be maintained across code generation cycles is:

  • Generate the entities
  • Manually add relationships and other custom code (such as transient attributes, constants, etc) to the generated entities. i.e.:
  • @OneToOne, @OneToMany, @ManyToMany including making columns read-only (as needed).
    
  • Test the relationships to verify they work as expected.
  • Add relationship code to the dal4j configuration file including read-only columns.
  • IMPORTANT: Make sure to back-up the code hand modified and tested in steps 2 & 3 above, just in case...
  • Re-generate the code and verify relationships have been added as expected
  • In the sample application (samples/round-trip) a @OneToOne unidirectional relationship from User to Customer is added to src/com/dal4j/sample/simple/ejb/entity/User.java. In order for the relationships to be maintained across code generation cycles, it has been added to bin/config-mysql.xml and bin/config-sqlserver.xml.

    Test code for this project can be seen in the src/com/dal4j/sample/simple/app/TestApp.java file.

    Entity Relationships

    The XML structure for relationship mappings to be manually injected into
    generated entity beans is as follows:

    <relationships>
        <table>
            <name>...</name>
            <readOnlyColumns>
                <!-- @Column(name="XYZ", insertable=false,updatable=false) -->
                <readOnlyColumn>..</readOnlyColumn>
            </readOnlyColumns>
            <injectCode><![CDATA[ /* RELATIONSHIP CODE GOES HERE */ ]]></injectCode>
        </table>
    </relationships>
    

    For Example, below shows relationship mappings for SOME_TABLE. Columns COLUMN_NAME1 and COLUMN_NAME2 will be made read-only. In addition, the code found in <injectCode>...</injectCode> will be added to the generated code.

    <relationships>
        <table>
            <name>SOME_TABLE</name>
            <readOnlyColumns>
                <!-- Columns annotated with insertable=false,updatable=false -->
                <readOnlyColumn>COLUMN_NAME1</readOnlyColumn>
                <readOnlyColumn>COLUMN_NAME2</readOnlyColumn>
            </readOnlyColumns>
            <injectCode><![CDATA[
    // Code to be added when SOME_TABLE entity is generated
    private SomeObject mSomeObject;
    public void setSomeObject (SomeObject pVal) { mSomeObject = pval; }
    @OneToOne(cascade={CascadeType.ALL},fetch=FetchType.EAGER)
    @JoinColumn(name="SOME_JOIN_COLUMN_NAME")
    public SomeObject getSomeObject() { return mSomeObject; }
            ]]></injectCode>
        </table>
        <!-- Add additional relationship mapipings here -->
    </relationships>
    

    Global Imports and Annotations

    To add imports and class level annotations globally or to every generated pojo, add the <imports> and <classAnnotations> elements to your dal4j configuration file. For example:

    <entityBeanGenConfig>
    
        <driverClass>...</driverClass>
        ...
        <!--                                                                    -->
        <!-- Add @XmlRootElement annotation and import to all generated classes -->
        <!--                                                                    -->
        <imports>import javax.xml.bind.annotation.XmlRootElement;</imports>
        <classAnnotations>@XmlRootElement(name="$className")</classAnnotations>
    
        <views>
        ...
        </views>
        <relationships>
        ...
        </relationships>
    </entityBeanGenConfig>
    

    The following variables may be used for class annotations added globally or individually at the class level (described below):

    $className - The name of the entity class first letter lower case.
    $ClassName - The name of the entity class first letter upper case.
    $table_name - The name of the DB table used to generated the entity, lower case.
    $TABLE_NAME - The name of the DB table used to generated the entity, upper case.

    Customization of class imports, attribute annotations, get method annotations, and code injection
    The following describes how to apply imports, class level annotations, and custom code to a specific entity derived from either a table or a view.

    <relationships>
        <table>
            <name>TABLE_NAME</name>
            <imports>
        import com.dal4j.mypackage.MyClass;
        import java.util.Collection;
        import org.springframework.format.annotation.DateTimeFormat;
             </imports>
            <classAnnotations>
        @MyClassAnnotation(className="$ClassName", tableName="$TABLE_NAME")
            </classAnnotations>
            <!-- Add annotations to the get method for specific fields -->
            <columnProperties>
              <columnProperty>
                <columnName>user_created_date</columnName>
                <!-- Annotations added to the userCreatedDate attribute -->
                <!-- NOTE: Only available with SimplePojoCodeGenerator -->
                <injectFieldAnnotations>
                   @DateTimeFormat(pattern= "y-M-d")
                </injectFieldAnnotations>
                <!-- Annotations added to the getUserCreatedDate method -->
                <injectGetMethodAnnotations>
                   @DateTimeFormat(pattern= "y-M-d")
                </injectGetMethodAnnotations>
              </columnProperty>
              <columnProperty>
                <columnName>user_updated_date</columnName>
                <!-- NOTE: Only available with SimplePojoCodeGenerator -->
                <injectFieldAnnotations>
                   @DateTimeFormat(pattern= "y-M-d")
                </injectFieldAnnotations>
              </columnProperty>
            </columnProperties>
    
            <injectCode><![CDATA[
        public final static String SOME_CONST = "MyConstant";
        private Collection<MyClass> someList;
        public void setSomeList (Collection<MyClass> pValue) { someList = pValue; }
        @Transient
        public Collection<MyClass> getSomeList() { return someList; }
            ]]></injectCode>
    
        </table>
    </relationships>
    

    Note that the same applies to views, here is the above example but for a view:

    <views>
        <view>
            <name>VIEW_NAME</name>
            <primaryKeyColumn>view1_primary_key_column_name</primaryKeyColumn>
            <imports>
        import com.dal4j.mypackage.MyClass;
        import java.util.Collection;
            </imports>
            <classAnnotations>
        @MyClassAnnotation(className="$ClassName", tableName="$TABLE_NAME")
            </classAnnotations>
            <!-- Add annotations to the attribute or get method for specific fields -->
            <columnProperties>
              <columnProperty>
                <!-- Identifies column to be customized -->
                <columnName>user_created_date</columnName>
                <!-- Annotations added to the userCreatedDate attribute -->
                <!-- NOTE: Only available with SimplePojoCodeGenerator -->
                <injectFieldAnnotations>
                   @DateTimeFormat(pattern= "y-M-d")
                </injectFieldAnnotations>
                <!-- Annotations added to the getUserCreatedDate method -->
                <injectGetMethodAnnotations>
                   @DateTimeFormat(pattern= "y-M-d")
                </injectGetMethodAnnotations>
              </columnProperty>
              <columnProperty>
                <columnName>user_updated_date</columnName>
                <!-- NOTE: Only available with SimplePojoCodeGenerator -->
                <injectFieldAnnotations>
                   @DateTimeFormat(pattern= "y-M-d")
                </injectFieldAnnotations>
              </columnProperty>
            </columnProperties>
            <injectCode><![CDATA[
        public final static String SOME_CONST = "MyConstant";
        private Collection<MyClass> someList;
        public void setSomeList (Collection<MyClass> pValue) { someList = pValue; }
        @Transient
        public Collection<MyClass> getSomeList() { return someList; }
            ]]></injectCode>
        </view>
    </views>
    

    Related

    Wiki: Home

    MongoDB Logo MongoDB