org.hibernate.PropertyNotFoundException: Could not find a getter for XXX

使用过hibernate的同事一定对PropertyNotFoundException异常非常熟悉,产生原因也很好找,通常的错误原因有:

1. hibernate配制文件错误,属性里有空格等。

2.是get方法和属性不对应。

 

但是今天在开发过程中发现配制文件 和 get方法都没有错误,但是还是报PropertyNotFoundException异常。

PO 抽像类如下:

    private String gAccountId;

    /**
   * getGAccountId描述:
   *
   * @return 返回 gAccountId。
   */
  public String getGAccountId()
  {
   return gAccountId;
  }

  /**
   * setGAccountId描述:
   *
   * @param accountId 要设置的 gAccountId。
   */
  public void setGAccountId(String accountId)
  {
   gAccountId = accountId;
  }

hib.xml 如下:

<hibernate-mapping package="gmt.boss.interfaces.customer.po">

 <class name="TAccount" table="T_ACCOUNT">

  <property name="gAccountId" column="G_ACCOUNT_ID" type="java.lang.String" />

 

 **********

所以我一直认识配制的没有错误,但是一到buildSessionFactory时就报异常。

想了很久发现 get 方法最可能出错,于是把getGAccountId() 改成getgAccountId();显然这是不符合javabean的命名规范的,但是问题竟然解决了。反编译了hibbernate代码发现hibbernate是这么处理的,首先利用配制文件的package 和 name 找到要映射到的类,按上面的配制文件就是 gmt.boss.interfaces.customer.po.TAccount,然后利用反射取出这个类的信息,取的时候利用了缓存的机制,不是每次都反射一次。然后用这个类的信息中的get,set方法 和 配制文件中进行匹配。以上面的getGAccountId()为例, 先去掉这个方法中的前三位取余下的部分为flag1 = GAccountId,然后调用jdk中的Introspector.decapitalize把这个字符串dropCase 得到flag2, 然而 Introspector.decapitalize dropCase的过程,如果这个字符串开头为一个以上的大写字母,那就不做任何操作反回原串,,所以flag2 =GAccountId 。

匹配的过程为只要 flag1 与flag2 中有一个和 配制文件中的property name一致就为正确的映射。GAccountId 显然和 <property name="gAccountId" column="G_ACCOUNT_ID" type="java.lang.String" />无法匹配,抛出

 PropertyNotFoundException 也就很自然了。

最后把配制文件改成

<property name="gaccountId" column="G_ACCOUNT_ID" type="java.lang.String" />

抽像类改成

    private String gaccountId;

    /**
   * getGAccountId描述:
   *
   * @return 返回 gAccountId。
   */
  public String getGaccountId()
  {
   return gaccountId;
  }

 问题 OK了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值