domaframework / doma-codegen-plugin

Generates Java, Kotlin, and SQL files from Database

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

schemaNameは効かないです。

gikeihi opened this issue · comments

rootユーザーを使う場合、schemaNameを指定しても、すべてDBのテーブルを対象になります。
build.gradle

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        // specify your JDBC driver
        classpath 'mysql:mysql-connector-java:8.0.13'
    }
}

plugins {
    id 'java'
    // specify the Doma CodeGen Plugin with correct version
    id 'org.seasar.doma.codegen' version '1.3.1'
}

domaCodeGen {
    // make an arbitrary named block
    dev {
        // JDBC url
        url = 'jdbc:mysql://localhost:3306/dba'
        // JDBC user
        user = 'root'
        // JDBC password
        password = 'xxxx'
        schemaName = 'dba'
        // configuration for generated entity source files
        entity {
          packageName = 'jp.co.xxx.common.entity'
          showSchemaName = true
          overwrite = false
          useListener = false
        }
    }
}

DBは「dba」だけではなく、「dbb, dbc」などがあります。
gradle domaCodeGenDevEntityを実行すると、dbb, dbcのテーブルのentityも作成してしまいました。

JDBCのURLにdatabaseTermプロパティを指定して次のようにしてみるとどういう結果になるでしょうか?

jdbc:mysql://localhost:3306/dba?databaseTerm=SCHEMA

databaseTermプロパティ の詳細は次を見てください。
https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-connp-props-connection.html#idm46159178566048

ご回答ありがとうございます。
databaseTermを使っても効かないです。
記載忘れましたが、使っているMySQLのバージョンは「5.7.32」となっています。

ちょっとjdbc driverを使ってテーブルのmeta情報を取得しました。
やっぱり、schemaPatternではなく、catalogで制御しています。

下記のようになると、すべてテーブルのmeta情報をしまいます。

ResultSet tables = metaData.getTables(null, "dba", null, new String[]{"table"});

ただ、下記のようになると、"dba"のテーブルのmeta情報しか取れません。

ResultSet tables = metaData.getTables("dba", null, null, new String[]{"table"});

org.seasar.doma.gradle.codegen.meta.TableMetaReaderのソースを確認すると、catalogパラメータはnullを固定していますよね。

  protected List<TableMeta> getTableMetas(DatabaseMetaData metaData, String schemaName)
      throws SQLException {
    List<TableMeta> results = new ArrayList<TableMeta>();
    ResultSet rs =
        metaData.getTables(
            null, schemaName, null, this.tableTypes.toArray(new String[this.tableTypes.size()]));
    try {
      while (rs.next()) {
        TableMeta tableMeta = new TableMeta();
        tableMeta.setCatalogName(rs.getString("TABLE_CAT"));
        tableMeta.setSchemaName(rs.getString("TABLE_SCHEM"));
        tableMeta.setName(rs.getString("TABLE_NAME"));
        tableMeta.setComment(rs.getString("REMARKS"));
        if (isTargetTable(tableMeta)) {
          results.add(tableMeta);
        }
      }
      return results;
    } finally {
      JdbcUtil.close(rs);
    }
  }

テストコードも添付します。ご検討宜しくお願い致します。

    public static void main(String[] args) throws SQLException {
        DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());
        String url = "jdbc:mysql://localhost:3306/dba";
        Connection con = DriverManager.getConnection(url, "root", "xxxx");
        System.out.println("Connection established......");
        DatabaseMetaData metaData = con.getMetaData();
        ResultSet tables = metaData.getTables("dba", null, null, new String[]{"table"});
        while (tables.next()) {
            System.out.println("Table name: "+tables.getString("Table_NAME"));
            System.out.println("Table type: "+tables.getString("TABLE_TYPE"));
            System.out.println("Table schema: "+tables.getString("TABLE_SCHEM"));
            System.out.println("Table catalog: "+tables.getString("TABLE_CAT"));
            System.out.println(" ");
        }
    }

申し訳ございません、私は下記リンクの情報を見漏れました。
https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-connp-props-connection.html#idm46159178566048
databaseTermは、mysql-connector-javaのバージョン8.0.17から有効になります。
ただ、mysql-connector-javaのバージョンを「8.0.17」に変更してもエラーが発生します。
gradle.build

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        // specify your JDBC driver
        classpath 'mysql:mysql-connector-java:8.0.17'
    }
}

plugins {
    id 'java'
    // specify the Doma CodeGen Plugin with correct version
    id 'org.seasar.doma.codegen' version '1.3.1'
}

domaCodeGen {
    // make an arbitrary named block
    dev {
        // JDBC url
        url = 'jdbc:mysql://localhost:3306/dba'
        // JDBC user
        user = 'root'
        // JDBC password
        password = 'xxxx'
        schemaName = 'dba'
        // configuration for generated entity source files
        entity {
          packageName = 'jp.co.xxx.common.entity'
          showSchemaName = true
          overwrite = false
          useListener = false
        }
    }
}

エラー情報:

* What went wrong:
Execution failed for task ':domaCodeGenDevDbMeta'.
> [DOMAGEN9001] The exception was thrown. java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.ms_admin where 1 = 0' at line 1

発生する場所は、StandardCodeGenDialect#isAutoIncrement

    String fullTableName = TableUtil.getQualifiedTableName(catalogName, schemaName, tableName);
    String sql = "select " + columnName + " from " + fullTableName + " where 1 = 0";

MySqlは、ディフォルトにcatalogNameはdef, 指定したschemaNameはdba、エラーログのテーブルを例として、
結局sqlは下記のようになりました。

String sql = "select xxx from def.dba.ms_admin where 1 = 0";

上記sqlを実行すると、エラーが発生しました。

詳細な報告ありがとうございます。

catalogNameというプロパティを追加してバージョン1.4.0としてリリースしました。

現在の設定で

schemaName = 'dba'

と指定しているところを下記のように変更してお試しください。

catalogName = 'dba'

早速のご対応ありがとうございました。
下記のように設定すると、無事にソースを生成できました!

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        // specify your JDBC driver
        classpath 'mysql:mysql-connector-java:8.0.17'
    }
}

plugins {
    id 'java'
    // specify the Doma CodeGen Plugin with correct version
    id 'org.seasar.doma.codegen' version '1.4.0'
}

domaCodeGen {
    // make an arbitrary named block
    dev {
        // JDBC url
        url = 'jdbc:mysql://localhost:3306/dba'
        // JDBC user
        user = 'root'
        // JDBC password
        password = 'xxxx'
        catalogName= 'dba'
        // configuration for generated entity source files
        entity {
          packageName = 'jp.co.xxx.common.entity'
          showCatalogName = true
          overwrite = false
          useListener = false
        }
    }
}

一つ気になるところですが、showCatalogName = trueを指定すると、生成されたEntityのアノテーション@tableにはcatalog = "weshow"となっています。これはdoma2はちゃんと処理できるかどうか、まだテストしていないです。
やっぱりMySqlは面倒くさいですよね。
showCatalogName = trueのケースは少ないので、とりあえず、今のままで使用させていただきます。

本当にありがとうございました!

@Entity(metamodel = @Metamodel)
@Table(catalog = "dba", name = "ms_admin")
public class MsAdmin extends AbstractMsAdmin

showCatalogName = trueを指定すると、生成されたEntityのアノテーション@tableにはcatalog = "weshow"となっています

私の環境では再現できなかったのですが、再現条件さえわかれば修正したいと思います。
一旦このissueはクローズしますがもし条件わかったら別のissueであげていただけると嬉しいです。