1. 程式人生 > >hibernate常見錯誤彙總

hibernate常見錯誤彙總

1. 插入失敗,某一欄位沒有預設值:insert fail;filed depid doesn't have a default value

     這個錯誤往往是你丈二和尚—摸不著頭腦,因為它並沒有提示哪一行錯誤,也沒說清為什麼錯誤;筆者經過層層排錯找出了錯誤:這是資料庫中的錯誤,說depid欄位沒有預設值是因為建表的時候depid不允許為空,而你在save()的時候往往都是先不插入外來鍵的,只在commit()的時候hibernate後臺會執行一句updatesql語句更新進去外來鍵。所以讓他允許為空就ok了。

2. myeclipse中沒有報錯,但是就是資料庫中楞寫不進去資料,這是原因呢?

原因一:你的配置檔案中少了一對映的語句,即hibernate.cfg.xml中少了一句<mapping resource="com/hbsi/one2many/Employee.hbm.xml"/>;沒有這句話則無法對映到資料庫。

原因二:還是配置檔案中的錯,以下這些語句一定要寫對,錯一不可

<propertyname="dialect">

org.hibernate.dialect.MySQLDialect</property>

<property name="connection.url">

jdbc:mysql://localhost:3306/hibernate</property>

        <property name="connection.username">root</property>

        <property name="connection.password">root</property>

        <property name="connection.driver_class">

com.mysql.jdbc.Driver</property>

尤其是方言那條語句,即dialect中的資料庫一定要對應,如果你用的是mysql語句一定要用mysql的方言, org.hibernate.dialect.MySQLDialect是總概述,也有不同版本對應的方言,如果你標上了資料庫的版本號則要寫對應版本號的mysql資料庫;這裡容易犯錯的就是一般配置檔案都是從模版檔案中拷來然後修改的,而模版檔案中一般方言會是hsql,就是hibernate自帶的,如果這麼寫可以對映到mysql資料庫,但是會有一些錯誤,比如你是時間型別,這種型別可以分日期date、時間time、日期時間datetmie三種類型,資料庫型別分別對應類中不同型別,這時寫數屬性property的時候就要指明type型別,但是用hsql即使指明瞭也不起作用,而且你指明create表而不是更新表也不起作用。

3. 測試的時候出錯,並值提示一句話:空指標nullPointException

這種錯誤也很讓人糾結,控制檯報了好多錯,但是都不是一目瞭然的,報的錯也許你檢查好久怎麼都是對的,但是愣說那幾句有錯,原因也有很多。

原因一:這種是不是錯誤的錯誤;為什麼這麼說呢!?這種錯誤常見於查詢方法,尤其是根據id查詢的方法,比如你資料庫中沒有你要查詢的id就會出現空指標異常。

原因二:配置檔案中的屬性標籤寫錯,<property name="show_sql">true</property>;這裡標籤為property,但是寫多properties,手一哆嗦就容易寫成後者,所以如果出現這樣的錯你不妨去看看這個檔案是寫錯了,這個粗就是個指東打西的錯,控制檯不會清楚的給你指出是什麼錯,只會告訴說某個類屬性找不到或無法對應更甚者,其他的屬性值都對了,資料庫與之對應的也對就是唯獨某一個屬性沒有插進資料庫,這時就有可能是property這個標籤的錯誤了,可以看看是否粗心寫錯了。

 原因三:具體請看下面這個按id查詢的模版方法:

publicvoid find(){

try{

session = HibernateUtil.getSession();

Customer cus = (Customer)session.get(Customer.class,4);

Set<Orders> ord = cus.getOrd();

System.out.println(ord.size());

}catch(Exception e){

e.printStackTrace();

}finally{

HibernateUtil.close();

}

該方法中,session = HibernateUtil.getSession();這句尤為重要,如果這句忘了寫,或被你忽視了,那你就等著空指標找你吧!

 原因四:配置檔案中的mapping標籤錯誤

問題出多出在你做測試的時候,比如你測試一對一關係表的基於外來鍵和基於主鍵的操作測試的時候,你可能會建兩個包,一個用來測試基於外來鍵的,一個用來基於主鍵的;這時裡面的類都是一樣的,只是包不同,你在hibernate.cfg.xml配置檔案中配置的時候會出現兩個不同包中的xxx.hbm.xml檔案。比以下這種情況:

<!--

<mapping resource="com/hbsi/many2one/Employee.hbm.xml"/>

<mapping resource="com/hbsi/many2one/Department.hbm.xml"/>

-->

<mappingresource="com/hbsi/one2many/Employee.hbm.xml"/>

<mappingresource="com/hbsi/one2many/Department.hbm.xml"/>

請尊重別人的勞動成果,轉載請指明:http://blog.csdn.net/tianyazaiheruan

4 .常見的Unknown entity錯

   一般出現這種錯,一般都是對映錯誤,有可能是配置檔案中的,有可能是類對應的對映檔案中的。

(1).Unknown entity: java.util.HashSet問題

主要是以下問題,下面程式碼是錯誤的程式碼:

Customer cus =new Customer();

Set<Orders> ord =new HashSet<Orders>();

Orders order1 =new Orders();

Orders order2 =new Orders();

cus.setOrd(ord);

session.save(ord);   //這裡方法中傳入的是ord

session.save(order1);

session.save(order2);

正確的程式碼

Customer cus =new Customer();

Set<Orders> ord =new HashSet<Orders>();

Orders order1 =new Orders();

Orders order2 =new Orders();

cus.setOrd(cus);  //應該傳入的是cus

session.save(ord);

session.save(order1);

session.save(order2);

(2) Unknownentity:com.entity.TestEntity問題

排出這個錯誤

      1)看看entity中,不能為空的屬性,有沒有set();

      2)在META-INF \persistence.xml,有沒有宣告你的entity

      最後發現自己,在persistence.xml沒有加下面這句導致了Jpa Unknown entity:

1.                              <class>com.entity.TestEntity</class> 

persistence.xml

1.                              <?xml version="1.0" encoding="UTF-8"?> 
2.                              <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> 
3.                                  <persistence-unit name="JpaTest" transaction-type="RESOURCE_LOCAL"> 
4.                                  <provider>org.hibernate.ejb.HibernatePersistence</provider> 
5.                                  <class>com.entity.TestEntity</class> 
6.                                  <exclude-unlisted-classes>true</exclude-unlisted-classes> 
7.                                  <properties> 
8.                                      <property name="hibernate.connection.driver_class" value="oracle.jdbc.driver.OracleDriver"/> 
9.                                      <property name="hibernate.connection.url" value="jdbc:oracle:thin:@localhost:1521:orcl"/> 
10.                                  <property name="hibernate.connection.username" value="ningnian"/> 
11.                                  <property name="hibernate.connection.password" value="ningningx"/> 
12.                                  <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/> 
13.                                  <property name="hibernate.show_sql" value="true" /> 
14.                                  <property name="hibernate.hbm2ddl.auto" value="update"/>          
15.                              </properties> 
16.                              </persistence-unit> 
17.                          </persistence> 

(3) Unknown entity: java.lang.Object問題

錯誤日誌:

嚴重: Servlet.service() for servlet spring3 threw exception
org.hibernate.MappingException: Unknown entity: java.lang.Object

程式碼:

                IvceConfigInfo ivceConfigInfo = getConfigInfoByKey(id);    //通過主鍵查詢到需要更新的資料

                ivceConfigInfo.setInitName(key); // 設定更新的值
                ivceConfigInfo.setValue(value); // 設定更新的值
                this.update(ivceConfigInfo); // 此句發生上述錯誤

改為 this.update("IvceConfigInfo", ivceConfigInfo);  即可

4Unknown entity: java.lang.Stringjava.lang.Integer問題

解決辦法:刪除也要指定其欄位

public void delete(int id) {
  Session session=HibernateUtil.getSession();
  session.beginTransaction();
  //session.delete(id); 錯誤程式碼的根源
  String hql = "DELETE Admin WHERE id=?";
  Query q = session.createQuery(hql);
  q.setInteger(0, id);
  q.executeUpdate();
  session.getTransaction().commit();
  HibernateUtil.closeSession(session);
 }

public void delete(String userName) {
  Session session=HibernateUtil.getSession();
  session.beginTransaction();

  String hql = "DELETE Admin WHERE userName=?";
  Query q = session.createQuery(hql);
  q.setString(0, userName);
  q.executeUpdate();
  session.getTransaction().commit();
  HibernateUtil.closeSession(session);
 }

處理異常多了發現其實只要看其主要的提示程式碼,還是可以找到原因的,特別是細節問題...今天就遇到了一個什麼HibernateUtil類沒有初始化的,找到其具體原因,其實就是一個數據庫表中的較長的欄位屬性名給寫錯了,弄的報錯說找不到該屬性的get()、set()方法,剛開始還以為根本沒錯呢...

5. xxx.hbm.xml中錯誤

Must specify an identifier type  id的唯一性,xxx.hbm.xml中id沒有給他寫名字;

determine entity name  xxx.hbm.xml中class沒有寫名字,會報錯找不到實體類

請尊重別人的勞動成果,轉載請指明:http://blog.csdn.net/tianyazaiheruan

6. 級聯操作時的錯誤

object references an unsaved transient instance - save the transient instance before flushing: com.hbsi.orders_o2mboth.Customer(物件引用一個未儲存的瞬態例項——儲存瞬時例項之前,沖洗:com.hbsi.orders_o2mboth.Customer);出現這種錯,多出在雙向級聯表中,是因為你級聯操作時出的錯,比如你讓單方放棄了操作inverse=”true”,又讓單方進行級聯操作 cascade=”save-update”;因為你讓它放棄了操作,這時你在用增刪改或者測試的時候就會把相應單方的程式碼省去,也應該省去,這時這些程式碼其實沒有起作用,就是無用的程式碼。如以下:

/*Set<Orders> ords = new HashSet<Orders>();

        ords.add(ord1);

        ords.add(ord2);

        session.save(cus);*/

但是問題就出現了,你不寫單方操作的程式碼但是級聯操作又放在多方操作的xxx.hbm.xml中(單方沒有放的情況下),肯定會出錯了,相當於沒有想資料庫插入單方資料。這時你要避免這樣的錯誤,可以把級聯操作的程式碼放到多方的xxx.hbm.xml中:<many-to-one name="cus" column="cid" cascade="save-update"/>

7. 不是錯誤的錯

有時候報錯:什麼關閉時異常,說這句錯誤HibernateUtil.close();(注:這裡的hibernateUtil方法是自己編寫的util工具,不一定特指這個類,一般都是myeclipse自動生成的util工具類)這時不是util類裡的錯,可能是你try語句中引用的程式碼出錯了,只是這句close()在finally裡,所以不管對與錯它都執行的原因,這時找錯可以忽略這句,就是說可以先註釋掉這句,再依次找錯。

8. Could not execute JDBC batch update

不能執行jdbc資料庫的批量更新。這個錯誤的解決方法:

在多方設定級聯操作的同時,把單方的級聯操作去掉,並且把多方那邊的inverse=true”也去掉,這時你操作出來的資料是刪除多方資料的某一條的同時把單方級聯的資料也刪除,並且把多方剩下與單方級聯的外來鍵資料設定為空

9. attribute "cascade" must be declared for element type for "one-to-many"

翻譯過來是:屬性“cascade”必須被宣告為元素型別為一對多,這個錯誤的原因是:我爸級聯操作和放棄操作inverse="true" cascade="save-update"放在了<one-to-many class="Orders"/>這個標籤屬性上。

錯誤修改:正確的完整格式應該是:

<setname="ord"inverse="true"cascade="save-update">

 <key column="cid"/>

 <one-to-manyclass="Orders"/>

</set>

10.Unable to resolve property:idCard

無法解決的屬性:idCard

錯誤分析:IdCard.hbm.xml對映檔案中出錯,<one-to-one name="IdCard" cascade="save-update"/>;name屬性值錯誤,name的取值都是某個類的屬性值,所以應該是idCard

請尊重別人的勞動成果,轉載請指明:http://blog.csdn.net/tianyazaiheruan

11.傻瓜式錯誤

   注意包名和類名,對映檔案和配置檔案中的一定要和現實中的額、一樣,不一樣會找不到,提示找不到的錯誤的時候,你就可以朝著是不是包名或類名寫錯了或是不一樣。尤其是下面這些位置的:

<hibernate-mapping package="com.hbsi.many2many">

<class name="Course" table="course">

<mappingresource="com/hbsi/many2many/Student.hbm.xml"/>

<mappingresource="com/hbsi/many2many/Course.hbm.xml"/>

<setname="course"table="student_course"cascade="save-update">

<keycolumn="student_id"/>

<many-to-manycolumn="course_id"class="Course"/>

</set>

12.          Duplicate collection role mapping com.hbsi.many2manyboth.Student.course和

Attribute "Class" must be declared for element type "many-to-many".這個錯一般同時出現,主要原因是後者引起的。Many-to-many沒有Class這樣的屬性,,這裡的錯誤的原因是,小寫的class在many-to-many等這樣的元素中是型別屬性,但是如果誤寫成大寫的就會出錯

錯誤寫法:

<many-to-many Class="Student" column="student_id"/>

正確寫法:

<many-to-many class="Student" column="student_id"/>

13.duplicate entry 2-2 for key prymary

   主鍵重複,這個錯誤多發在多對多的關係中,這是因為你兩邊同時維護,有沒有讓其中一方放棄維護,這是中間表會重複插入外來鍵,因為一般中間表的兩個外來鍵又是它的主鍵,這時就會出現主鍵重複的情況,一方放棄維護即可解決問題。

14.Attribute "inverse" must be declared for element type "many-to-one".

   屬性“反向”必須被宣告為元素型別“多對一”。如果你在多方設定了反轉,即讓多方放棄了維護,那麼你在測試的時候就不能用多方來呼叫測試,否則會出現上面的錯誤。

15.Attribute "cloumn" must be declared for element type "element".

  屬性“cloumn”必須被宣告為元素型別“元素”。這是什麼錯呢!?其實很簡單,就是這句話<element type="string" cloumn="hobbies_name" not-null="true"/>;element標籤的column屬性寫錯了。

請尊重別人的勞動成果,轉載請指明:http://blog.csdn.net/tianyazaiheruan

16.The content of element type "list" must match "(meta*,subselect?,cache?,synchronize*,comment?,key,(index|list-index),(element|one-to-many|many-to-many|composite-element|many-to-any),loader?,sql-insert?,sql-update?,sql-delete?,sql-delete-all?,filter*)".

出現這一堆錯誤的時候,是因為你用的是list高階對映,但是你沒有寫<list-index column="position"/>,這裡是為表產生一個唯一位置識別符號。這裡list標籤所特有的子標籤,不寫會報錯。

18. class com.hbsi.component.Ablum not found while looking for property: id

   對映檔案出錯。<class name="Album" table="ablum">;這裡的型別屬性name的值寫錯的緣故。所以一定要細心,尤其用到自己不熟悉的英語單詞的時候一定要細心,如果怕出錯就在多處用到的同一個單詞都從一個正確的位置複製一下。

19.The content of element type "union-subclass" must match "(meta*,subselect?,synchronize*,comment?,tuplizer*,(property|many-to-one|one-to-one|component|dynamic-component|properties|any|map|set|list|bag|idbag|array|primitive-array)*,union-subclass*,loader?,sql-insert?,sql-update?,sql-delete?,resultset*,(query|sql-query)*)".

元素型別的內容“union”必須匹配;union-subclass標籤的子標籤與joined-subclass不一樣,前者沒有key子標籤,後者有,這個錯是因為畫蛇添足,多了個key子標籤。

錯誤:<union-subclassname="Skiller"table="skiller">

      <keycolumn="emp_id"/>

    <propertyname="skill"/>

   </union-subclass> 

正確:<union-subclassname="Skiller"table="skiller">

    <propertyname="skill"/>

   </union-subclass> 

20.Cannot use identity column key generation with <union-subclass> mapping for: com.hbsi.extend.Employee

    Id型別不對,這種錯多出在繼承對映中;而且是每個具體類一張表的情況 ;id的型別必須是hilo的(hilo在其他博文中有介紹,感興趣的可以去看看),否則就會出上面的錯。

<idname="empId">

<generatorclass="hilo"/>

</id>

21.Attribute "table" must be declared for element type "subclass".

屬性“表”必須被宣告為元素型別”子類”。這個問題多出在混合使用“一個類繼承體系一張表”和“每個子類一張表” (對映檔案)這種型別的對映中。請看下面的錯誤語句

<subclassname="Skiller"table="skiller">

  <propertyname="skill"/>

</subclass>

正確的語句是:

<subclassname="Skiller">

  <propertyname="skill"/>

</subclass>

這是因為這種混合表的使用就是要使某一個子類與父類在同一個表中,而上面的錯誤語句卻標明瞭table="skiller",這不是背道而馳麼。

ps:原文轉載自http://blog.csdn.net/yangkai_hudong/article/details/8434812