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:
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:
@OneToOne, @OneToMany, @ManyToMany including making columns read-only (as needed).
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>