其實本來沒啥大問題,但到網上查的時候發現了一些誤人子弟的說法,所以還是記下來吧。
現象:
hibernate從低版本升級到某一個版本時(我們是升到4.3.10)時,在程序啟動時會報錯:
java.lang.NoSuchMethodError: javax.persistence.Table.indexes()[Ljavax/persistence/Index;
於是查資料,網上也有許多人遇到同樣的錯誤,並且發現的原因是在model中使用了@Table(name="xxx")這個注解所致,於是推薦的改法是將這個標簽去掉,改用@Entity(name="xxx")這個注解,甚至有人說是新版的hibernate不支持@Table這個注解了。
其實不然。
在Hibernate的新新官方文檔中,明確提到了@Table這個注解:
@Table lets you define the table the entity will be persisted into. If undefined, the table name is the unqualified class name of the entity.
當然你可以不寫這個注解,那麼表名默認就是非限定類名(也就是不帶包的類名)。但企圖使用@Entity(name="xxx")來代替,把這裡的xxx作為表名來看卻是大錯特錯了,@Entity中的nama屬性表示的是重新定義實體名:
@Entity.name lets you define the shortcut name of the entity you can use in JP-QL and HQL queries. It defaults to the unqualified class name of the class.
這裡的默認也是非限定類名。這個實體名就是你在Hql中使用的(比如“from xxx")那個model名稱,一般這個名稱不要重新定義,直接用類名就OK,更不要把它當做表名,除非你的表名和實體名一模一樣。
回到那個異常,這個問題如何解決呢?可以肯定的是,這個問題是由jar包沖突引起的,hibernate的注解基礎部分現在都采用JPA的注解了,JPA是屬於javaEE的一部分,許多javaEE的包中也包括了JPA 的相關API,這個問題可能就是由於項目中存在javaEE相關的jar包,與hibernate所包含的JPA相關的jar包版本有沖突。
解決辦法一:刪除沖突的jar包
首先排查下項目Lib庫,發現類似的jar包要檢查下,比如有人發現這些包ejb3-persistence.jar,javaee.jar,可以解開看一下,如果裡面有javax.persistence這個包名,估計就找到問題jar包了。處理方法要麼把這些包刪除,如果一定需要,那也要升級個別的版本試試,或者把jar包裡的java.persistence下樣關的內容刪除,再重新打包。
解決辦法二:針對resin服務器中的jar包沖突
但我們項目遇到了更怪僻的問題,lib庫中沒有相關的javaee包,無法用上面所說的方法。找來找去,終於發現,我們用的resin服務器,resin自帶的系統庫裡有一個javaee-16.jar的包。但不論是刪除這個Jar包還是重新編譯,resin均報錯。又google出去,終於找到解決方法:
在resin.xml文件最後加上一句:
<class-loader>
<servlet-hack/>
</class-loader>
Hibernate3.1.2_中文文檔PDF http://www.linuxidc.com/Linux/2016-02/128462.htm
Hibernate學習入門教程 http://www.linuxidc.com/Linux/2015-08/121498.htm
在Hibernate中開啟日志 http://www.linuxidc.com/Linux/2015-07/120499.htm
Hibernate+JUnit測試實體類生成數據庫表 http://www.linuxidc.com/Linux/2015-07/120161.htm
Hibernate整體理解 http://www.linuxidc.com/Linux/2014-07/104405.htm
Hibernate的映射機制 http://www.linuxidc.com/Linux/2014-12/110265.htm
Hibernate 的詳細介紹:請點這裡
Hibernate 的下載地址:請點這裡