Description
I encountered an unexpected behavior when using Spring Boot with Thymeleaf to bind a boolean property with a field name starting with is (e.g., isTest). Spring fails to recognize the property when using the full name (isTest) in a binding expression, but succeeds with the derived name (test).
This suggests an ambiguity in how Spring’s Java Bean property resolution handles boolean properties with is prefixes. This issue was also reported to Thymeleaf, but it may originate from Spring’s property accessor.
Steps to Reproduce:
- Create a simple bean with a boolean property:
package com.project.model;
public class TestBean {
private boolean isTest;
public boolean isTest() {
return isTest;
}
public void setIsTest(boolean value) {
this.isTest = value;
}
}
- Create a controller:
@Controller
public class TestController {
@GetMapping("/test")
public String showTestForm(Model model) {
model.addAttribute("bean", new TestBean());
return "test";
}
}
- Create a Thymeleaf template (test.html):
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><title>Test</title></head>
<body>
<form th:action="@{/test}" th:object="${bean}" method="post">
<label>Test : <input type="checkbox" th:field="*{test}"></label>
<button type="submit">Submit</button>
</form>
</body>
</html>
-
Run the application and access /test. It works fine.
-
Change th:field="{test}" to th:field="{isTest}" and access /test again.
Expected Behavior:
Either both th:field="{test}" and th:field="{isTest}" should work consistently, or both should fail with a clear error indicating a naming convention issue.
Spring should properly handle boolean properties with is prefixes in field names, aligning with Java Bean conventions.
Actual Behavior:
th:field="{test}" works, even though the field is named isTest. The getter isTest() is called, and the checkbox binds correctly.
th:field="{isTest}" fails with:
org.springframework.beans.NotReadablePropertyException: Invalid property 'isTest' of bean class [com.project.model.TestBean]: Bean property 'isTest' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
Changing the setter parameter name (e.g., from test to value) does not affect the success of th:field="*{test}".
Environment:
Spring Framework: 6.2.3 (based on spring-webmvc-6.2.3.jar in logs)
Spring Boot: 3.4.3
Thymeleaf: 3.1.3.RELEASE
Java: 21
OS: Windows 11
Suggestion:
Add a note in the Spring Framework documentation (e.g., https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-beans) about this behavior for boolean properties with is prefixes.
Clarify that th:field="*{something}" works when the getter is isSomething(), even if the field is named isSomething.
Consider whether this tolerance is intentional or should be flagged as an inconsistency.
Activity