在利用hibernate做ORM时,如果对于hbm文件的属性,在java的pojo类中没有对应的get和set方法,则会产生如下异常:
java 代码
- Caused by: org.hibernate.PropertyNotFoundException: Could not find a getter for auditInfos
- in class EventType
- at org.hibernate.property.BasicPropertyAccessor.createGetter(BasicPropertyAccessor.java:282)
- at org.hibernate.property.BasicPropertyAccessor.getGetter(BasicPropertyAccessor.java:275)
- at org.hibernate.mapping.Property.getGetter(Property.java:272)
但是今天遇到了一种情况,就是写上某个属性的get和set方法时,同样会出现该异常,该pojo的属性是eTypeName则对应的方法名称为getETypeName();跟踪hibernate的堆栈报错信息,查找到:
org.hibernate.property.BasicPropertyAccessor.createGetter的private static Method getterMethod(Class theClass, String propertyName)方法,其中对于get的处理逻辑是这样的:
java 代码
- private static Method getterMethod(Class theClass, String propertyName) {
-
- Method[] methods = theClass.getDeclaredMethods();
- for (int i=0; i
-
- if ( methods[i].getParameterTypes().length==0 ) {
- String methodName = methods[i].getName();
-
-
- 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];
- }
-
- }
-
-
-
-
- if ( methodName.startsWith("is") ) {
- String testStdMethod = Introspector.decapitalize( methodName.substring(2) );
- String testOldMethod = methodName.substring(2);
- if ( testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName) ) {
- return methods[i];
- }
- }
- }
- }
- return null;
- }
这里methodName的值为getETypeName,propertyName的值为eTypeName,利用java.beans.Introspector进行对第一个字母的小写化操作得到testStdMethod,去掉get得到的是testOldMethod。
但是问题就出来了,前者的小写操作是有前提的,根据源码可知:
java 代码
- public static String decapitalize(String name) {
- if (name == null || name.length() == 0) {
- return name;
- }
- if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
- Character.isUpperCase(name.charAt(0))){
- return name;
- }
- char chars[] = name.toCharArray();
- chars[0] = Character.toLowerCase(chars[0]);
- return new String(chars);
- }
对于第一个字符和第二个字符都是大写的情况下,则返回的是原来的字符,因此在这种情况下,去掉get的ETypeName在decapitalize之后仍然是ETypeName,所以两者都得到的是ETypeName,而不再执行第14行代码,所以private static Method getterMethod(Class theClass, String propertyName)得到的是null,因此会产生对于某某属性找不到get方法的异常出来。
解决办法可以将getETypeName改成geteTypeName,或者干脆将属性名改成ETypeName。