[[JHipster]] * 目次 [#w384ffb3] #contents * 目的 [#xcc771be] コード生成で、いけてないコードを生成するのだがテンプレートでどうなっているのか見つけたい。 このページは、そのコード生成を探すまでの自分のメモである。 * jhipsterのテンプレートの場所を調べる [#s7128a99] ** jsonからエンティティを読み込んでいるファイル [#y079b47b] node_modules\generator-jhipster\jdl\converters\jdl-to-json\jdl-without-application-to-json-converter.js 上記ファイルの、以下のコードでentityが格納されていると思う。 setFields(); setRelationships({ unidirectionalRelationships }); ** jhipsterをEverythingというアプリで検索してみる [#a261c63a] node_modules\generator-jhipster というフォルダにテンプレートがありそうな感じがする。 * ejs [#af57737e] テンプレートの拡張子はejsだ。VS-CODEの拡張を入れておくと、コメントされているかどうかが、見やすくなった。 * どこにGREPをかけるか [#sfff10b9] *** GREP対象のフォルダ [#ba6c9772] node_modules\generator-jhipster\generators *** GREPのファイル名 [#x47cb113] *.ejs * 外部PKの場合、生成される画面でリンクの文字列がIDになっている件 [#vf649f50] name属性があれば、そっちをリンクするように指定したい。 まず、調べる用と思うのは、どのテンプレートが外部キーのIDをWEB画面に生成するようなコードを書いているのか?ということだ。 ** テンプレートの箇所 [#u5208d53] おそらく、 node_modules\generator-jhipster\generators\entity-client\templates\react\src\main\webapp\app\entities\entity.tsx.ejs で、一覧を出していると思う。forを使っているところをさがしてみよう。 このへんが、怪しそう <%_ for (field of fields) { _%> <th<% if (!paginationNo) { %> className="hand" onClick={sort('<%= field.fieldName %>')} <%_ } _%>><Translate contentKey="<%= `${i18nKeyPrefix}.${field.fieldName}` %>"><%= field.fieldNameHumanized %></Translate><% if (!paginationNo) { %> <FontAwesomeIcon icon="sort" /><% } %></th> <%_ } _%> <%_ for (relationship of relationships) { _%> <%_ if (relationship.relationshipManyToOne || (relationship.relationshipOneToOne && relationship.ownerSide) || (relationship.relationshipManyToMany && relationship.ownerSide && paginationNo)) { _%> <th<% if (!paginationNo) { %> <% } %>><Translate contentKey="<%= `${i18nKeyPrefix}.${relationship.relationshipName}` %>"><%= relationship.relationshipNameHumanized %></Translate><% if (!paginationNo) { %> <FontAwesomeIcon icon="sort" /><% } %></th> <%_ } _%> <%_ } _%> いや、これは<TD>タグだから、タイトルだな。 リンクのところは以下のようになっている。 <td> <Button tag={Link} to={`${match.url}/${<%= entityInstance %>.<%= primaryKey.name %>}`} color="link" size="sm"> {<%= entityInstance %>.<%= primaryKey.name %>} </Button> </td> ここのprimaryKey.nameではなく、そのエンティティを文字列で表現するフィールド、例えばnameフィールドがあればそれを使うようにすると、自分がイメージすることが解決する。 では、このprimaryKey.nameはどこで格納されているのだろうか? ** primaryKey.nameの格納場所 [#o8664b8c] * エンティティの生成箇所 [#xf6735bd] entity-server ** クラスのメンバー変数は、テンプレートではどうあつかわれているのか? [#b761e9c1] fields に格納されており、ループして、各fieldsをとっている of fields 実際にループは以下のようにされている <%_ for (const field of fields.filter(field => !field.transient && (embedded || !field.id || !primaryKey.composite))) { _%> public <%= field.javaFieldType %> get<%= field.fieldInJavaBeanMethod %>() { return this.<%= field.fieldName %>; } * SpringBootのJPAでは、private変数にスネーク形式のfield.fieldNameをつかってはいかんのだよ [#ze96c980] JPAの問い合わせ構文はフィールドがキャメル形式であることが必要である。 ちょっと昔は、スネーク形式はアンダーバーを2個付けたらJPAでもつかえるとかしていたらしいけど、かっこわるいから、そのやり方は使えなくなっている。 * fieldのcamel形式は、どうやって取得するのか? [#l235b8bb] get<%= field.fieldInJavaBeanMethod %>() とあるから、 field.fieldInJavaBeanMethod で取得できそうだ。 あとは、そのキャメル形式のフィールド名の先頭が小文字だったらいいのだがなにかあるのだろうか? 型は、javaFieldTypeのようだ * fieldInJavaBeanMethod や、javaFieldTypeの値はどこでいれているのか? [#edbc8edd] 以下で値を詰め替えているようだが、generatorsフォルダ以下では無いようだ node_modules\generator-jhipster\generators\entity-server\templates\src\main\java\package\service\criteria\EntityCriteria.java.ejs * utilフォルダのfields [#id6072c1] ** 変数を格納しているコードの場所 [#q5b432e7] node_modules\generator-jhipster\utils\multi-step-transform\field.js ** コード内容 [#z398fa41] if (field.fieldNameAsDatabaseColumn === undefined) { const fieldNameUnderscored = _.snakeCase(field.fieldName); const jhiFieldNamePrefix = generator.getColumnName(entityWithConfig.jhiPrefix); if (isReservedTableName(fieldNameUnderscored, entityWithConfig.prodDatabaseType)) { if (!jhiFieldNamePrefix) { generator.warning( `The field name '${fieldNameUnderscored}' is regarded as a reserved keyword, but you have defined an empty jhiPrefix. This might lead to a non-working application.` ); field.fieldNameAsDatabaseColumn = fieldNameUnderscored; } else { field.fieldNameAsDatabaseColumn = `${jhiFieldNamePrefix}_${fieldNameUnderscored}`; } } else { field.fieldNameAsDatabaseColumn = fieldNameUnderscored; } } field.columnName = field.fieldNameAsDatabaseColumn; * fieldにはどんな変数が格納されているのだろう。 [#i199af29] | fieldのメンバ変数 | 実際の値 | * fieldにはどんな変数が格納されているのだろう。 [#i199af29] | fieldのメンバ変数 | | | id| | | fieldName | | | fieldType | | | mapstructExpression | | | transient | | | readonly | | | autoGenerate | | | liquibaseAutoIncrement | | | jpaGeneratedValue | | | autoGenerateByService | | | autoGenerateByRepository | | | jpaGeneratedValue | | | fieldIsEnum | | | fieldWithContentType | | | fieldTypeBlobContent | | | fieldNameAsDatabaseColumn | | | columnName | | | fieldNameAsDatabaseColumn | | | fieldInJavaBeanMethod | | | fieldValidateRulesPattern | | | fieldValidateRulesPatternJava | | | fieldValidateRulesPatternAngular | | | fieldValidateRulesPatternReact | | | fieldValidate | | | field.fieldValidateRules | | | field.unique | | | generateFakeData | | | path | | | uniqueValue | | | relationshipsPath | | | reference | | | javadoc | | | fieldNameHumanized | | | fieldName | | | fieldType | | | fieldNameCapitalized | | | fieldName | | どうやって確認しようか。 * もしかしたら、snake形式は、entityの定義に入らない前提になってる? [#b2cbc0e7] そうだった .jipsterフォルダのエンティティのフィールド名にスネーク形式が入ると、 そのまま、スネーク形式でjavaのエンティティ名となってしまい、 JPAのやり方に沿っていないフィールド名となってしまう。 続けるかどうか、確認ダイアログがでてほしい。 * snake形式だったら、エラーを吐いて停止してほしいが、どこでjsonを読んでいるのか? [#qe7a1e6d]