Edited at

Doma-Genで生成するentityをカスタマイズする。 (entityの内容を変更。)

More than 1 year has passed since last update.

doma-genで生成されるentityの内容をカスタマイズした時に調べた内容をまとめました。自分の場合は、型の変更とアノテーションの要素を追加をしましたが、基本的にはfreemarkerの変更で完結するので、他の場合でも応用が利くと思います。

まず簡単に言ってしまうと、以下をすれば編集は完了します。

①genのパラメータにtemplatePrimaryDir="xxx"を追加。

②entity.ftl を変更。


「①genのパラメータにtemplatePrimaryDir="xxx"を追加。」

templatePrimaryDirとは公式ドキュメントを参照すると「テンプレートファイルを検索する際の優先ディレクトリです。独自テンプレートファイルを使用する場合に指定します。」と書かれています。

指定は適当に決めてください。動作検証時に自分は、仮の設定としてアプリケーションルート「.」と指定しました。

例) src/main/resources/doma/template

http://doma.seasar.org/extension/doma_gen_gen_task.html


「②entity.ftl」

entity.ftlとはentityを生成するtemplateファイルです。このファイルを編集すればentityの生成内容を変更できます。

(1)entity.ftlを入手する。

entity.ftlはdoma-gen-2.13.0.jarの中にあります。解凍してファイルを取得してください。

※同バージョンのソースを入手できれば、そちらでも良いと思います。

▼ファイルの場所

org/seasar/doma/doma-gen/2.13.0/org/seasar/doma/extension/gen/template/entity.ftl

(2)entity.ftlを「templatePrimaryDir」に指定したディレクトリに配置する。

(3)entity.ftlを編集する。

※編集後のファイル


entity.ftl

<#-- このテンプレートに対応するデータモデルのクラスは org.seasar.doma.extension.gen.EntityDesc です -->

<#-- (1)カスタマイズfunction定義 -->
<#function convertDataType dataType>
<#local result = dataType?replace("Byte", "Integer")>
<#local result = result?replace("int", "Integer")>
<#local result = result?replace("Short", "Integer")>
<#return result>
</#function>
<#function addElement columnName>
<#if columnName == "create_time">
<#return ", insertable=false">
<#elseif columnName == "updated_datetime">
<#return ", insertable=false, updatable=false">
</#if>
<#return "">
</#function>
<#-- (1)カスタマイズfunction定義 -->

<#import "/lib.ftl" as lib>
<#if lib.copyright??>
${lib.copyright}
</#if>
<#if packageName??>
package ${packageName};
</#if>

<#list importNames as importName>
import ${importName};
</#list>

/**
<#if showDbComment && comment??>
* ${comment}
</#if>
<#if lib.author??>
* @author ${lib.author}
</#if>
*/
@Entity<#if useListener || namingType != "NONE">(</#if><#if useListener>listener = ${listenerClassSimpleName}.class</#if><#if namingType != "NONE"><#if useListener>, </#if>naming = ${namingType.referenceName}</#if><#if useListener || namingType != "NONE">)</#if>
<#if showCatalogName && catalogName?? || showSchemaName && schemaName?? || showTableName && tableName??>
@Table(<#if showCatalogName && catalogName??>catalog = "${catalogName}"</#if><#if showSchemaName && schemaName??><#if showCatalogName && catalogName??>, </#if>schema = "${schemaName}"</#if><#if showTableName><#if showCatalogName && catalogName?? || showSchemaName && schemaName??>, </#if>name = "${tableName}"</#if>)
</#if>
public class <#if entityPrefix??>${entityPrefix}</#if>${simpleName}<#if entitySuffix??>${entitySuffix}</#if><#if superclassSimpleName??> extends ${superclassSimpleName}</#if> {
<#list ownEntityPropertyDescs as property>

<#if showDbComment && property.comment??>
/** ${property.comment} */
<#else>
/** */
</#if>
<#if property.id>
@Id
<#if property.generationType??>
@GeneratedValue(strategy = ${property.generationType.referenceName})
<#if property.generationType == "SEQUENCE">
@SequenceGenerator(sequence = "${tableName}_${property.columnName}"<#if property.initialValue??>, initialValue = ${property.initialValue}</#if><#if property.allocationSize??>, allocationSize = ${property.allocationSize}</#if>)
<#elseif property.generationType == "TABLE">
@TableGenerator(pkColumnValue = "${tableName}_${property.columnName}"<#if property.initialValue??>, initialValue = ${property.initialValue}</#if><#if property.allocationSize??>, allocationSize = ${property.allocationSize}</#if>)
</#if>
</#if>
</#if>
<#if property.version>
@Version
</#if>
<#if property.showColumnName && property.columnName??>
<#-- (2)アノテーションに要素追加 -->
@Column(name = "${property.columnName}"${addElement(property.columnName)})
</#if>
<#-- (3)変数の型変換 -->
<#if !useAccessor>public </#if>${convertDataType(property.propertyClassSimpleName)} ${property.name};
</#list>
<#if originalStatesPropertyName??>

/** */
@OriginalStates
<#if entityPrefix??>${entityPrefix}</#if>${simpleName}<#if entitySuffix??>${entitySuffix}</#if> ${originalStatesPropertyName};
</#if>
<#if useAccessor>
<#list ownEntityPropertyDescs as property>

/**
* Returns the ${property.name}.
*
* @return the ${property.name}
*/
<#-- (4)戻り値の型変換 -->
public ${convertDataType(property.propertyClassSimpleName)} get${property.name?cap_first}() {
return ${property.name};
}

/**
* Sets the ${property.name}.
*
* @param ${property.name} the ${property.name}
*/
<#-- (5)引数の型変換 -->
public void set${property.name?cap_first}(${convertDataType(property.propertyClassSimpleName)} ${property.name}) {
this.${property.name} = ${property.name};
}
</#list>
</#if>
}


編集内容の説明をします。

コメント:(1)カスタマイズfunction定義 の箇所

とコメントを打っている箇所は

A)引数で受けた型文字列を変換するconvertDataTypeメソッドです。

※変換仕様

Byte→Integer

int→Integer

Short→Integer

B)引数で受けたカラム名文字列がcreate_time or update_timeの場合にアノテーションに追加する文字列を返すaddElementメソッドです。

※仕様

create_timeの場合、", insertable=false" を返す。

update_timeの場合、", insertable=false, updatable=false" を返す。

それ以外は""を返す。

コメント:(2)アノテーションに要素追加 の箇所

@Columnの記載箇所でaddElementメソッドに呼び、アノテーションの要素をカスタマイズしています。

コメント:(3)変数の型変換 の箇所

とコメントを打っている箇所は

フィールド変数の記載箇所でconvertDataTypeを呼び、型をカスタマイズしています。

コメント:(4)戻り値の型変換 の箇所

とコメントを打っている箇所は

getterメソッドの記載箇所でconvertDataTypeを呼び、戻り値の型をカスタマイズしています。

コメント:(5)引数の型変換 の箇所

とコメントを打っている箇所は

setterメソッドの記載箇所でconvertDataTypeを呼び、引数の型をカスタマイズしています。

以上です。

freemarkerの構文さえ分かれば、entity生成をカスタマイズできるので

ぜひ試していただければと思います。