SpringBootでH2の管理コンソールを使う #springboot

spring:h2:console:enabled をtrueにするだけ。

spring:
  datasource:
    driver-class-name: org.h2.Driver
    url: jdbc:h2:mem:testdb;MODE=MYSQL
    username: sa
    password:
  h2:
    console:
      enabled: true

SpringBoot起動後、下記にアクセスすると利用できる。 http://localhost:8080/h2-console

参考

web-dev.hatenablog.com

SpockでJavaの無名クラスを使ったらCircleCIがコケた #circleci #java #spock

CircleCIがテストの途中にタイムアウトでこけた。

command mvn test took more than 10 minutes since last output

ログを見ても途中で止まっており、結果としてもタイムアウトなので検討つかない。
もちろんローカル環境では発生しない。

RevertなりなんなりしながらTry&Errorを行うと、どうもSpockでインターフェースを返すメソッドをMockにする際、無名クラスを使っているところが原因の模様。

インターフェースはこんな感じ

public interface HomeCarePlanner {
  String getName();
}

テストはこんな感じ

given:
def hogeMock = new Hoge(){
    @Override
    String getName() {
        return 'dummy'
    }
}
hogeService.get(*_) >> hogeMock

対応

無名クラスを使わずに、GroovyMockしてあげたら発生しなくなった。
根本原因は分からない。。(´・ω・`)

def hogeMock = Mock(Hoge)
hogeMock.getName() >> 'dummy'
hogeService.get(*_) >> hogeMock

ジョイ・インクを読んだ #JoyInc #ポエム

「ジョイ・インク 役職も部署もない全員主役のマネジメント」を読んだ。

ある意味ぶっ飛んだ会社の話。

突拍子もないいくつもの仕組みが、「なぜ、そうするのか」次々に裏付けされていく。
どういう文化にしたいのか、どう向かっていくのか。

そして終盤、筆者のエモーショナルなメッセージは胸を打つ。

そうだよ、仕事には喜びがなければいけない。

成功が幸福を運んでくるのではない。
幸福になると成功するのだ。

人生の終わりに、「もっと家族との時間を過ごしておけばよかった」なんて思うことがあってはいけない。

喜びを目指そう。
自分を、家族を、仲間を、ユーザーを、喜ばせよう。

明日家を出て仕事に向かう時、思わず口笛を吹いてしまうような喜びを。

ジョイ・インク 役職も部署もない全員主役のマネジメント

ジョイ・インク 役職も部署もない全員主役のマネジメント

JavaのStreamで独自ソート #java

sortedにComparator

Streamで独自ソートするにはsortedにComparatorを渡してやればOK

List<Person> personsSortedByName = getPersons().stream()
  .sorted(new Comparator<Person>() {
    @Override
    public int compare(Person person1, Person person2) {
        return person1.getName().compareTo(person2.getName());
    }
  }).collect(Collectors.toList);

Lambdaで書けます

List<Person> personsSortedByName = getPersons().stream()
  .sorted((person1, person2) -> person1.getName().compareTo(person2.getName()))
  .collect(Collectors.toList);

Comparator#comparing が使えます

List<Person> personsSortedByName = getPersons().stream()
  .sorted(Comparator.comparing(Person::getName))
  .collect(Collectors.toList);

逆順にしたい

逆順にしたいときは Comparator#reversed を使えばOKです。

List<Person> personsSortedByName = getPersons().stream()
  .sorted(Comparator.comparing(Person::getName).reversed())
  .collect(Collectors.toList);

参考

www.task-notes.com

SpockでオーバーロードされたメソッドをMockする #spock #groovy

JavaオーバーロードされたメソッドをMockしようとしても、うまくMockできないことがある。
どちらのメソッドを呼べばいいかわからないからだと思う。(たぶん)

下記のようなメソッドをMockしたい場合の対応。

public String doSomething(String arg1)
public String doSomething(String arg1, String arg2)

仮引数を明記する

オーバーロードされたメソッドをMockするには、Closureの仮引数を明記することで、対応可能。

// これだとうまくMockされない
doSomething(*_) >> {'もっくできないー'}

// 仮引数を明記するとうまくいく
doSomething(*_) >> {param1 -> '引数1個の方'}
doSomething(*_) >> {param1, param2 -> '引数2個の方'}

MissingMethodException

なお同じテストメソッド内で、両方のメソッドを呼ぼうとすると MissingMethodException が発生することがある。
※Mockしているのが片方だけであっても発生する

groovy.lang.MissingMethodException: No signature of method

これはMockしている引数を明示すると解決できる。

doSomething(_ as String) >> {param1 -> '引数1個の方'}
doSomething(_ as String, _ as String) >> {param1, param2 -> '引数2個の方'}

参考

hideoku.hatenablog.jp

ORマッパーへの違和感が少し晴れた気がする

前からあった違和感

(リレーショナル)データベースのモデリングドメインモデリングは違うっていうのを前から思っていて、それからDBとドメインのオブジェクトをそのまま結びつけるようなORマッパーにはずっと違和感を覚えていたのだ。

だからMyBatisみたいなSQLマッパー(っていう呼び方が合ってるのかは分からない)の方が好きだったりする。
必要に応じてドメインモデルへの詰め替えをデータアクセスレイヤでやることも抵抗ない。

じゃあその違和感って何だろう

これまでは、「データベースにとっての最適化とドメインモデルは必ずしも一致しないから」っていう表現をしていたんだけど、先日たまたま会社の研修が大きなヒントになって理解が進んだ。

データはそれ自体では意味を持たない

講師の方が「データ」と「情報」という表現をしていて、

データ: それ自体では意味のないもの 情報: データを加工して意味(価値)を持たせたもの

あぁ、なるほどな、と。
データベースのモデリングはデータを扱うもので、ドメインモデルは情報を扱うものなんだな、と。
そりゃあ違うよね、と。

※講義の内容はデータベースに特化したもので、自分の中で勝手につながっただけである

まとめ

実際にはデータベースに全く要件的な(意味のある)要素が入ってこないなんてことはありえないし、システムの規模やフェーズによっては敢えて2つのモデリングを切り離さないという選択もあると思う。
それがORマッパーなのかもしれない。
詳しくないけど、Railsなんかもそうだよね多分。

ただデータ周りを整理や設計する時だったり見直す時、データと情報ってことを意識すると結構役に立つかもしれない。

いずれにせよ、自分の中では割りと大きめなブレークスルーだったかも。

SpringBootのWebAPIでResponseのJSONをPretty Printにする #springboot

SpringBootでWeb APIを作ってる時に、ResponseのJSONをPretty Printにしたくなった時の対応。

やりたいこと

こういうのを

{"hoge":[123,456],"huga":"Yeah!","piyo":{"code":"AA1234","name":"Bob"}}

こういう感じにしたい

{
  "hoge" : [ 123, 456 ],
  "huga" : "Yeah!",
  "piyo" : {
    "code":"AA1234",
    "name":"Bob"
  }
}

結論

ObjectMapperをカスタマイズする。
カスタマイズにはいくつか方法がある。

application.ymlを変更する

spring.jackson.serialization.indent_output=true にすれば、それだけでOK

YAMLだとこんな感じ。

spring:
  jackson:
    serialization:
      indent_output: true

ObjectMapperを自前で用意する

独自Serializer等のために自前でObjectMapperを用意していたりすると、前述の方法は使えない。

Primaryにしている自前のObjectMapperに対して、Pretty Printを有効にしてやる必要がある。

/**
 * 独自ObjectMapper
 */
@Bean
@Primary
public ObjectMapper jsonObjectMapper() {
    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(myModule());

    // Pretty Printにする
    mapper.enable(SerializationFeature.INDENT_OUTPUT);
    
    return mapper;
}

独自ObjectMapperを活用しつつ、application.ymlで変更できるようにする

ObjectMapperのカスタマイズ具合にもよるのかもしれないけれど、やっぱり設定ファイルで気軽に変更できるようにしたい。

そういう時はSpringBootを真似してObjectMapperを生成してやるとよさそう。

/**
 * 独自ObjectMapper
 */
@Bean
@Primary
public ObjectMapper jsonObjectMapper(Jackson2ObjectMapperBuilder builder) {
    // Jackson2ObjectMapperBuilderを引数に追加
    // Bootを真似してObjectMapperを生成
    ObjectMapper mapper = builder.createXmlMapper(false).build();
    mapper.registerModule(myModule());
    
    return mapper;
}

こうすると、最初と同じようにapplication.ymlの変更でPretty Printを切り替えられる。

参考