Goalist Developers Blog

Doma-GenでMySQLのテーブルCOMMENTを取得する(Doma2)

どうも。ゴーリストのJPです。

今回はDoma2でJavaソースを自動生成する際に、MySQLのテーブルCOMMENTが取れなくて困ったので、解決方法を書きたいと思います。

Doma2とは

JavaのORマッパーです。
DBを読み込み、EntityやDaoクラスのJavaソースの自動生成もしてくれます。
Welcome to Doma — Doma 2.0 ドキュメント

環境情報

  • MacOS Sierra 10.12.6
  • Java8
  • doma-gen 2.16.1
  • mysql 5.6.29

何が起きたのか

Entityクラスのテンプレートファイル(Free Marker)のJavadocにテーブルCOMMENTを使用します。
テーブルCOMMENTにはテーブルの論理名が登録されています。

  • テーブル名:sample_table
  • テーブルCOMMENT:サンプル

entity.ftl

/**
 * ${comment}テーブルエンティティ
 */
// @アノテーションは省略
public class <#if entityPrefix??>${entityPrefix}</#if>${simpleName} implements BaseTableEntity, EntityTrail {

実行結果

/**
 * テーブルエンティティ
 */
// @アノテーションは省略
public class SampleTable implements BaseTableEntity, EntityTrail {

テーブルCOMMENTが反映されていません。。。
本来なら「サンプルテーブルエンティティ」となってほしいです。

原因

MySQL用のjdbcDriverの不具合のようです。

MySQL Bugs: #65213: Connector/J does not retrieve the table comment in a InnoDB table

対策

DB接続時のuseInformationSchemaプロパティを「true」に指定すると不具合を回避できるようです。
具体的には、以下の手順で指定します。

GlobalFactoryを自作する

GlobalFactoryとはGenタスクで使用する各種クラスを生成するクラスです。

doma-gen/GlobalFactory.java at master · domaframework/doma-gen · GitHub

上記のGlobalFactoryを継承して、DataSourceクラスを生成するメソッドをOverrideします。
ここで、useInformationSchemaプロパティを「true」に指定します。

public class SampleGlobalFactory extends GlobalFactory {

  @Override
  public DataSource createDataSource(Driver driver, String user, String password, String url) {
    MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
    mysqlXaDataSource.setUseInformationSchema(true);
    mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
    mysqlXaDataSource.setUrl(url + "?useUnicode=true&characterEncoding=UTF-8");
    mysqlXaDataSource.setUser(user);
    mysqlXaDataSource.setPassword(password);
    return mysqlXaDataSource;
  }

}

Genタスクのパラメータを追加する

Genタスクの書かれたbuild.gradleにglobalFactoryClassNameパラメータを追加します。

task gen << {
  // 省略
  ant.gen(
        url: 'jdbc: sample',
        // 省略
        globalFactoryClassName: 'path.to.SampleGlobalFactory'
  )
}

Genタスクで使用するGlobalFactorySampleGlobalFactoryに変更してくれます。
これにより、useInformationSchemaプロパティが「true」のDataSourceを使用してMySQLに接続してくれるようになります。

再実行

ちゃんと出ました。

/**
 * サンプルテーブルエンティティ
 */
// @アノテーションは省略
public class SampleTable implements BaseTableEntity, EntityTrail {

まとめ

意外と調べてもこの方法が出てこなかったので、書いてみました。
調べるまでもないことなのか、テーブルCOMMENTはGenタスクで使われないのか、調べる能力が足りないのか、、、
この記事が誰かの役に立つことを願っています。