LoginSignup
0
0

Kotlin x Thymleafで Bean property 'isXXX' is not readable or has an invalid getter method

Last updated at Posted at 2024-02-16

事象

Kotlinのdata classで プロパティ名がis始まりだとThymleaf側でgetterがないと怒られる

testClass
data class TestForm(
    var id: Int = 0,
    var isPublished: Boolean = false  // これに対してgetterがないよと言われる。
}
thymleafのview
<div th:value="${testForm.isPublished}"></div>
error
Bean property 'isPublished' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?

原因

is始まりの場合は、getter、setterの命名規則が違うから。

プロパティ名 getter setter
hoge getHoge setHoge
isHoge isHoge setHoge

どうしてこうなってるのか

  • Java の Bean規約に従っているため

以下でダウンロードできる。
https://download.oracle.com/otndocs/jcp/7224-javabeans-1.01-fr-spec-oth-JSpec/

上記から抜粋したもの

8.3.2 Boolean properties
In addition, for boolean properties, we allow a getter method to match the pattern:
public boolean is<PropertyName>();
This “is<PropertyName>” method may be provided instead of a “get<PropertyName>” method, or it may be provided in addition to a “get<PropertyName>” method.
In either case, if the “is<PropertyName>” method is present for a boolean property then we will
use the “is<PropertyName>” method to read the property value.
An example boolean property might be:
public boolean isMarsupial();
public void setMarsupial(boolean m);

is始まりと言ったらbooleanだよね。だったらbooleanのプロパティのgetterもis始まりにするね。
的なことが書かれている。

という理解で大体OKだが、自分の中で少し気になったので書いておく↓

今回のケースをもう少し厳密にかくと、
Kotlinは実行するためにJavaコードに変換している。
そのときのルールというのも一応ある。基本的には、上記JavaBeansの規約とほぼ同等。
https://kotlinlang.org/docs/java-to-kotlin-interop.html#properties

ほぼと言っているのは、Javaではbooleanのgetterは全てis始まりにするというのが軸になっている(風に見受けられる)が、kotlinのData ClassからJavaに変換する際は、boolenaかどうかではなく、単純に名前がis始まりかを見ているから。
実際にkotlinのdata classをjavaのコードに変換してみてみるとわかりやすいです。
https://qiita.com/ke__kyukyun1828/items/384972110df2152bf530

例えば、booleanのtestFlagというプロパティのgetterは、JavaBeansの思想だとisTestFlagになりそうだが、kotlin to Javaにおいては getTestFlagとシンプルにgetを接頭辞につけたものになる。

対策

  • getterを自分で作る(getterが2つできるのは気持ち悪い&何か問題起きそう)
    • 例えば、 isTestというプロパティについて、 getIsTestを作る。
  • アノテーションで任意のgetter、setter名にする(これならまだアリなのかも)
  • そもそもis始まりの名前を使わない。
    • 予期しない動作は防げるかも。でもちゃんとコメントしておかないと後であれこれis始まりがよくない?ってなりそう

まとめ

is始まりのプロパティ名のgetter、setterは別ルールが適用されるよ。
基本的に問題起きないけど、ライブラリとか(今回はThymelaf)で、このルールに対応できていないものもあるのでそういうところは気を付ける。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0