雑にKotlinでSpring触ってみた件

雑にKotlinでSpringを触ったメモ。

2020/04/29

  • SpringにはSpringMVC, RESt, Fluxなどあるので混同しないように注意しなければならない

  • @Component SprintBoot。

  • @Service@RepositoryはSpringMVC

  • data classでは、JPAにマッピングできない

    • 結論、できる
    • https://www.baeldung.com/kotlin-jpa
    • identityがないと起動時エラーになる。@Idとかを付与しよう
      • org.springframework.beans.factory.BeanCreationException: Error creating bean with name ’entityManagerFactory’ defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: No identifier specified for entity: com.example.demo.Customer

    • dataclassではどうしてもNotNull型では定義できない
  • data classでは、バリデーションが効かない?

  • バリデーション

  • リレーション

    • 作れた
    • OneToManyとかManyToManyとか
      • fetchとcascadeは未調査
  • JPAのクエリをみたい

spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
  • foodRepsitory.findAll()

  • クリーンアーキテクチャ

    • DIどうする?
      • @Serviceとか@Repositoryとか使う?
      • これはSpringMVCの機能なので、RESTの場合は使えない?使わない方がいい
    • https://qiita.com/daisuzz/items/3e0cef338738143314bd
    • interfaceを継承しているクラスに@Componentを付与
      • デフォルトコンストラクタのうち、引数が0のものがないとbeenの生成が動かないので注意
        • これはだめ→class FoodInteractor(createdAt: LocalDateTime) : FoodBoundary {...
      • できてないと beenの生成時にエラーが出る
      • Parameter 4 of constructor in com.example.demo.interfaces.RestSampleController required a bean of type ‘com.example.demo.application.FoodBoundary’ that could not be found.`

    • @RestControllerでは、
      • コンストラクタに加えておけば勝手に注入してくれる
        • ただし、引数がないコンストラクタの場合のみ可能だったはず
        • private val foodBoundary: FoodBoundary
      • @Autowiredを使ってプロパティとして定義しておく
        • @Autowired private lateinit var boundary: FoodBoundary
      • どちらも同じインスタンスを参照していることに注意
  • 時間関係は、LocalDateTimeとLocalDateがカラムとして使える

  • created_atは Hibernateなら@CreationTimestamp@UpdateTimestampが利用できる

  • HibernateとかJPAの違いとか

  • JPA=Java Persistence API

  • Hibernateは最も成熟したツール?と書かれていたが???

  • Spring Restでエラー

  • @oneToManyでエラー

    • org.springframework.beans.factory.BeanCreationException: Error creating bean with name ’entityManagerFactory’ defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Collection has neither generic type or OneToMany.targetEntity() defined: com.example.demo.application.Customer.logs`

    • https://qiita.com/rinp/items/e1713e568a4eb79391e5
    • ListではなくMutableListを使う必要があったため
  • コンストラクタ

    • セカンダリコンストラクタは、 this()を継承する必要がある
  • OutputBoundaryの返り値は Anyにせざるを得ない!?!?

    • responseはControllerでするため、OutputBoundaryやInteractorは何かしらをreturnしなければならない
  • ほかにもちょこちょこAnyが出てきてしまった🚛

    • ControllerだとResponseEntity.ok(customer)とか
    • InputBoundaryだとfun purchase(customerId: Int, foodId: Int): Anyとか
  • どうすれば良い….

    • そもそも、PurchaseOutputはUsecase層だから知っててOKと気づいた
    • なので
      • Controllerに PurchaseOutputが出てきてもOK
      • Interactorに PurchaseOutputが出てきてもOK

2020/05/04

  • gradleの種類について

  • RESTのドキュメントを自動生成したい

    • Spring rest-docがそれにあたる
      • テストとしてコードを書かなければならない
    • ドキュメントからコードは、swaggerが最強
      • APIBlueprintはあまりメジャーではなかった
      • モデルまで出力してくれる
    • オンラインのswaggerエディタでよくね?
  • Kotlinのinout

    • 共変性のinと反変性のout
    • ジェネリクスをもったものをキャストする際に利用される。
  • Dockerイメージ化

    • こちらを参考に→https://spring.io/guides/gs/spring-boot-docker/
    • gradleでビルド
# syntax=docker/dockerfile:experimental
FROM openjdk:14-jdk AS build
WORKDIR /workspace/app
COPY . /workspace/app
RUN --mount=type=cache,target=/root/.gradle ./gradlew clean build
- jarファイル実行
FROM openjdk:14-jdk
COPY --from=build /workspace/app/build/libs/demo-0.0.1-SNAPSHOT.jar demo-0.0.1-SNAPSHOT.jar
ENTRYPOINT ["java","-jar", "demo-0.0.1-SNAPSHOT.jar"]
- 結局 `./gradle bootRun`でよかったんじゃないの?という気しかしない
  • HotReloading

    • こちらに書いてあった→https://stackoverflow.com/a/12744431/10040146
    • 1.IDEA(IntelliJ)のプラグインをgradleに読み込ませる
      • val developmentOnly by configurations.creating
      • developmentOnly("org.springframework.boot:spring-boot-devtools")
    • 2.main関数横の再生マークから起動せずに、gradleから起動設定をする
      • Edit Configuration
      • configをAdd
        • gradleProjectは現在のものを選択
        • Tasksは bootRun
        • Apply
      • configを登録後、起動
    • 3.kotlinファイル書き換えたりSpringのアノテーション書き換えると自動でビルドされる
      • どうやら編集したあとにカーソルを改行すると反映される?
      • もともとtemplateはビルドの必要ないので自動で反映される
    • 公式にも記述があった→https://docs.spring.io/spring-boot/docs/2.2.2.RELEASE/reference/htmlsingle/#using-boot-devtools-restart
  • exposed

    • 記述中

See also