基本的にはmysqldumpでwhereにjoinを使うにある通り、
1
|
|
というわけですが、肝は、
--where
中でJOIN
を使うためにsubqueryにする--single-transaction
を付けることでmysqldump: Couldn't execute 'SELECT... Table 'a' was not locked with LOCK TABLES (1100)
と言われるのを防ぐ
基本的にはmysqldumpでwhereにjoinを使うにある通り、
1
|
|
というわけですが、肝は、
--where
中でJOIN
を使うためにsubqueryにする--single-transaction
を付けることでmysqldump: Couldn't execute 'SELECT... Table 'a' was not locked with LOCK TABLES (1100)
と言われるのを防ぐある時、JHipsterのAngularのUser Managementを久し振りに見てみると、user名など表示されるのが物凄く遅いことがありました。ポツ、また数秒してポツ、という具合に一つ一つの行が表示されていきます。あれぇ? こんなもんだったかなぁ? あまり気にしなかったのですが、流石に新規Userを作成しようとして失敗する段になって、これは何とかしなければと思い始めました。browserでF12を押してみると、どうやらDate Pipeでのparseに失敗している様子。どうして? 前は出来てたのに。serverから来ているJSONをよく見ると、DBからのDateTime部分のObjectがepochSecond
とかnano何とかになっていました。検索すると、 Efficient way to have Jackson serialize Java 8 Instant as epoch milliseconds?を見付けて、中身読んでないですが「jackson-datatype-jsr310」を見掛けてあぁー!っと。
jhipsterで新規application作ってそのbuild.gradle
見てみると、確かにありましたcompile 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
。 これを、なくてもいいじゃん、と大分前に取っちゃってたんですね。確かにWebアプリ本体には影響なかったので気付きませんでした。あーあ。こういう影響が出てくるですか。なるほど。
JHipsterでuserを作る時にmail addressは必須で、 基本的にはnew user作るとJHipsterは裏でmailを投げています。 投げて失敗してもnew userは作れるんですが、passwordを設定できません。 どうしたらいいんだろう? と思ってlog見ていたら、 http(s)://ホスト名/#/reset/finish?key=XXXXXXXXXXXXXXX
にaccessすれば通常の手続きに乗れるんですね。 このkeyはどこで規定されるのかと思ったら、JHI_USER.RESET_KEY
の値です。 ここだけではダメで、JHI_USER.RESET_DATE
にnow()
等で日付時刻をsetしないと、そしてその時刻から24時間以内にaccessしないと、ならないです。 あるuserのpassword強制resetにも使える、と思います。
ただこれをやると、UserService#completePasswordReset
の中のcacheManager.getCache
でヌルポが出るようでどうしようもなかったです。なので、UserService.java
中のcacheManager.getCache(...)
を(当該method以外でも)全てtry...catch
で囲いました。だって無害でしょう?
追記: JHipsterでのlogin dialogには「パスワードを忘れましたか」というlinkがあって、 それを踏むとhttp://127.0.0.1:8080/#/reset/request
というpageに遷移し、 mail addressを入れると、上記初期登録時同様にActivateを要求するmailが飛びます。 初めてやってみました。へぇよく出来てますね。 そのmailに書いてあるURLも初期登録時同様http://127.0.0.1:8080/#/reset/finish?key=XXXXXXXXXX
です。
JHipsterでdatabaseのtableに新しいcolumnを足したいと思いました。 Liquibaseで管理されているので、直接DBを変えちゃうと立ち上がらなくなっちゃいます。 結構面倒臭いんですよねLiquibase。
基本的にはUsing JHipster in developmentのDatabase updatesに書いてある通り、です。 3通り紹介されていますが、最初に書かれているentity sub-generator
を使った方が、testやi18n、angular側の面倒も見てくれるので楽です。 但し、generateされるjava/json/ts filesについては、面倒でも一つ一つdiffを見て上書きするか考えた方がいいです。場合によっては上書きしない方がいいcaseもありました(repository class、即ちDBを直接叩くclassとかresource class、即ちRest Controllerとか、i18nのglobal.jsonとか、独自に書いたところがあるものは特に)。
新規にtableごと加える時はこれでいいのかもしれません(以前やってうまく行った薄い記憶がありますがよく覚えてません)。 けれども、既存tableにcolumnを足す、となると、 年月日_changelog.xml
を作ってくれないので、 いくらgradle
かけてもDBのtableを変更してくれないんです。 更に、checksumが合わないといって起動しなくなります。 困ります。
なので、2番目の策を合わせてchangelog.xml
を作ってもらいます。 そのためには上記ページに書いてあるように、一旦buildしてから、 gradle liquibaseDiffChangelog -PrunList=diffLog
すると、 class fileのdiffを取ってsrc/main/resources/config/liquibase/changelog/
以下にchangelogを作ってくれます。 それをsrc/main/resources/config/liquibase/master.xml
に手で書き入れてからbuildすると、changelogが働いてalter table
してくれます。 但しその際、元のtableのxml(年月日_added_entity_テーブル名.xml
)をもとに戻しておかないと、「checksumが合わない」と言われるでしょう。
...というように、1番目と2番目の合わせ技的なところが最良のように思います。
どうしてもうまく行かない時、最後は以下の手で何とかなります。なりました。
alter table
DATABASECHANGELOG.MD5CHECKSUM
にあるので自分でupdate table set ...
Angularを書いていて、 Type 'string' is not assignable to type 'number'.
と言われて驚いたので調べました。 えー、そのくらいよしなに変換してくれるんじゃないのー?! 結構型に厳しいんですね。 Typescript, toFixed. Type 'string' is not assignable to type 'number'に(12.32).toFixed(2)
とあるので試すとその通りでした。 この2ってなんだろう? と思ったら、「小数点以下第2位までの表示(第3位で四捨五入、無ければ0埋め)」ってことなんですね。