项目中遇到的一个问题,本文描述问题并分析解决问题,如有不正之处,欢迎批评指正。
问题是这样的:
数据库字段定义为:r_s,通过工具生成对应的 Hibernate 实体类和配置文件。
实体类代码:
private Double rS;
public void setRS(Double rs) {
this.rs = rs;
}
public Double getRS() {
return this.rs;
}
<property name="rS" type="java.lang.Double">
<column name="r_s" length="10" />
</property>
执行代码报错:Could not find a getter for “rS”。大约判定是属性 rS 与 getRS、setRS 不匹配的问题导致,于是把 getRS setRS 改为 getrS setrS,执行通过。问题是解决了,到底是什么原因导致的这个问题呢?
分析 Hibernate 代码,在 BasicPropertyAccessor.java 文件中存在如下代码:
String methodName = methods[i].getName();
// try "get"
if( methodName.startsWith("get") ) {
String testStdMethod = Introspector.decapitalize(methodName.substring(3));
String testOldMethod = methodName.substring(3);
if( testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName) ) return methods[i];
}
有两种方法从 get 方法中截取属性名称:
- 直接截取 methodName.substring(3);
- 通过 Introspector.decapitalize(methodName.substring(3)) 截取
Sun 给出的 Introspector.decapitalize 的注释说明:
but in the (unusual) special case when there is more than one character and both the first and second characters are upper case, we leave it alone.
大致意思:在特殊情况下,如果第一个、第二个都是大写字母,我们保持他的原态。这也就解释了上面的问题。getRS 中截取的属性为 RS,与实体类中的属性不一致,如果改为 getrS后,截取的属性为 rS,与实体类中的属相相匹配。
所以,在 Hibernate 的实体类中不要定义第一个、第二个都是大写字母的属性。